mercurial/cext/revlog.c
author Pierre-Yves David <pierre-yves.david@octobus.net>
Thu, 08 Apr 2021 00:01:11 +0200
changeset 47034 0d8ff1f4ab0c
parent 46974 3c9208702db3
child 47035 4f2b5f9d8cc4
permissions -rw-r--r--
revlog: add a `entry_binary` method on index The revlog index is already responsible for unpacking the binary entry, it would be simpler to make it responsible for packing them. In practice the C version of the index is already doing this internally. We introduce a "entry_binary" method that return the binary version of an existing revision. The method currently need to also take the revlog header to deal with the "first revision" special case. We will introduce further refactor in a later changeset to split that logic out. Differential Revision: https://phab.mercurial-scm.org/D10508
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
30112
9b6ff0f940ed parsers: move PyInt aliasing out of util.h
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30103
diff changeset
    26
#ifdef IS_PY3K
9b6ff0f940ed parsers: move PyInt aliasing out of util.h
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30103
diff changeset
    27
/* The mapping of Python types is meant to be temporary to get Python
9b6ff0f940ed parsers: move PyInt aliasing out of util.h
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30103
diff changeset
    28
 * 3 to compile. We should remove this once Python 3 support is fully
9b6ff0f940ed parsers: move PyInt aliasing out of util.h
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30103
diff changeset
    29
 * supported and proper types are used in the extensions themselves. */
30169
5f7151e6de85 parsers: alias more PyInt* symbols on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30112
diff changeset
    30
#define PyInt_Check PyLong_Check
30112
9b6ff0f940ed parsers: move PyInt aliasing out of util.h
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30103
diff changeset
    31
#define PyInt_FromLong PyLong_FromLong
30169
5f7151e6de85 parsers: alias more PyInt* symbols on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30112
diff changeset
    32
#define PyInt_FromSsize_t PyLong_FromSsize_t
30112
9b6ff0f940ed parsers: move PyInt aliasing out of util.h
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30103
diff changeset
    33
#define PyInt_AsLong PyLong_AsLong
9b6ff0f940ed parsers: move PyInt aliasing out of util.h
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30103
diff changeset
    34
#endif
9b6ff0f940ed parsers: move PyInt aliasing out of util.h
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30103
diff changeset
    35
38939
53bc73fae1a3 index: add pointer from nodetree back to index
Martin von Zweigbergk <martinvonz@google.com>
parents: 38938
diff changeset
    36
typedef struct indexObjectStruct indexObject;
53bc73fae1a3 index: add pointer from nodetree back to index
Martin von Zweigbergk <martinvonz@google.com>
parents: 38938
diff changeset
    37
38912
d1bc0e7c862b index: extract a type for the nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38911
diff changeset
    38
typedef struct {
d1bc0e7c862b index: extract a type for the nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38911
diff changeset
    39
	int children[16];
d1bc0e7c862b index: extract a type for the nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38911
diff changeset
    40
} nodetreenode;
d1bc0e7c862b index: extract a type for the nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38911
diff changeset
    41
43959
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43847
diff changeset
    42
typedef struct {
44066
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 43959
diff changeset
    43
	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
    44
	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
    45
	const char *(*index_node)(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
    46
	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
    47
} Revlog_CAPI;
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43847
diff changeset
    48
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
    49
/*
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
    50
 * 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
    51
 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
    52
 * 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
    53
 * 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
    54
 * Zero is empty
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
    55
 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
    56
typedef struct {
38939
53bc73fae1a3 index: add pointer from nodetree back to index
Martin von Zweigbergk <martinvonz@google.com>
parents: 38938
diff changeset
    57
	indexObject *index;
38912
d1bc0e7c862b index: extract a type for the nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38911
diff changeset
    58
	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
    59
	Py_ssize_t nodelen;
46224
fcc324a228fe revlog: use size_t for nodetree capacity
Jun Wu <quark@fb.com>
parents: 46144
diff changeset
    60
	size_t length;   /* # nodes in use */
fcc324a228fe revlog: use size_t for nodetree capacity
Jun Wu <quark@fb.com>
parents: 46144
diff changeset
    61
	size_t capacity; /* # nodes allocated */
fcc324a228fe revlog: use size_t for nodetree capacity
Jun Wu <quark@fb.com>
parents: 46144
diff changeset
    62
	int depth;       /* maximum depth of tree */
fcc324a228fe revlog: use size_t for nodetree capacity
Jun Wu <quark@fb.com>
parents: 46144
diff changeset
    63
	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
    64
} nodetree;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
    65
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
    66
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
    67
	PyObject_HEAD /* ; */
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
    68
	    nodetree nt;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
    69
} nodetreeObject;
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
    70
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
    71
/*
26098
ce26928cbe41 spelling: behaviour -> behavior
timeless@mozdev.org
parents: 26080
diff changeset
    72
 * 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
    73
 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
    74
 * 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
    75
 * 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
    76
 * 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
    77
 * end.
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
    78
 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
    79
 * 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
    80
 * 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
    81
 */
38939
53bc73fae1a3 index: add pointer from nodetree back to index
Martin von Zweigbergk <martinvonz@google.com>
parents: 38938
diff changeset
    82
struct indexObjectStruct {
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
    83
	PyObject_HEAD
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
    84
	    /* Type-specific fields go here. */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
    85
	    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
    86
	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
    87
	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
    88
	Py_buffer buf;          /* buffer of data */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
    89
	const char **offsets;   /* populated on demand */
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
    90
	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
    91
	unsigned new_length;    /* number of added elements */
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
    92
	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
    93
	char *added;            /* populated on demand */
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
    94
	PyObject *headrevs;     /* cache, invalidated on changes */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
    95
	PyObject *filteredrevs; /* filtered revs set */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
    96
	nodetree nt;            /* base-16 trie */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
    97
	int ntinitialized;      /* 0 or 1 */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
    98
	int ntrev;              /* last rev scanned */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
    99
	int ntlookups;          /* # lookups */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   100
	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
   101
	int inlined;
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   102
	long hdrsize; /* size of index headers. Differs in v1 v.s. v2 format */
38939
53bc73fae1a3 index: add pointer from nodetree back to index
Martin von Zweigbergk <martinvonz@google.com>
parents: 38938
diff changeset
   103
};
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   104
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   105
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
   106
{
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   107
	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
   108
}
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 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
   111
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
   112
22401
9ba8a93e55f5 parsers: ensure correct return type for inline_scan
Henrik Stuart <hg@hstuart.dk>
parents: 22400
diff changeset
   113
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
   114
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
   115
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
   116
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   117
#if LONG_MAX == 0x7fffffffL
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   118
static const char *const v1_tuple_format = PY23("Kiiiiiis#", "Kiiiiiiy#");
46875
651e6df2b0a4 clang-format: run the formatter on mercurial/cext/revlog.c
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
   119
static const char *const v2_tuple_format = PY23("Kiiiiiis#Ki", "Kiiiiiiy#Ki");
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   120
#else
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   121
static const char *const v1_tuple_format = PY23("kiiiiiis#", "kiiiiiiy#");
46875
651e6df2b0a4 clang-format: run the formatter on mercurial/cext/revlog.c
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
   122
static const char *const v2_tuple_format = PY23("kiiiiiis#ki", "kiiiiiiy#ki");
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   123
#endif
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   124
16863
bbedef66c6f3 parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents: 16787
diff changeset
   125
/* A RevlogNG v1 index entry is 64 bytes long. */
bbedef66c6f3 parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents: 16787
diff changeset
   126
static const long v1_hdrsize = 64;
bbedef66c6f3 parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents: 16787
diff changeset
   127
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   128
/* A Revlogv2 index entry is 96 bytes long. */
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   129
static const long v2_hdrsize = 96;
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   130
39219
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   131
static void raise_revlog_error(void)
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   132
{
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   133
	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
   134
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   135
	mod = PyImport_ImportModule("mercurial.error");
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   136
	if (mod == NULL) {
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   137
		goto cleanup;
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   138
	}
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   139
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   140
	dict = PyModule_GetDict(mod);
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   141
	if (dict == NULL) {
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   142
		goto cleanup;
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   143
	}
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   144
	Py_INCREF(dict);
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   145
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   146
	errclass = PyDict_GetItemString(dict, "RevlogError");
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   147
	if (errclass == NULL) {
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   148
		PyErr_SetString(PyExc_SystemError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   149
		                "could not find RevlogError");
39219
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   150
		goto cleanup;
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   151
	}
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   152
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   153
	/* 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
   154
	PyErr_SetString(errclass, "RevlogError");
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   155
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   156
cleanup:
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   157
	Py_XDECREF(dict);
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   158
	Py_XDECREF(mod);
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   159
}
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
   160
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   161
/*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   162
 * 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
   163
 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   164
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
   165
{
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   166
	if (pos >= self->length)
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   167
		return self->added + (pos - self->length) * self->hdrsize;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   168
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   169
	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
   170
		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
   171
			Py_ssize_t ret;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   172
			self->offsets =
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   173
			    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
   174
			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
   175
				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
   176
			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
   177
			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
   178
				return NULL;
864e9534d3d4 cext-index: propagate inline_scan error in `index_deref`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44066
diff changeset
   179
			};
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   180
		}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   181
		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
   182
	}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   183
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   184
	return (const char *)(self->buf.buf) + pos * self->hdrsize;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   185
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   186
40812
9cdd525d97b2 revlog: fix out-of-bounds access by negative parents read from revlog (SEC)
Yuya Nishihara <yuya@tcha.org>
parents: 40454
diff changeset
   187
/*
9cdd525d97b2 revlog: fix out-of-bounds access by negative parents read from revlog (SEC)
Yuya Nishihara <yuya@tcha.org>
parents: 40454
diff changeset
   188
 * 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
   189
 *
9cdd525d97b2 revlog: fix out-of-bounds access by negative parents read from revlog (SEC)
Yuya Nishihara <yuya@tcha.org>
parents: 40454
diff changeset
   190
 * 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
   191
 * 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
   192
 */
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   193
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
   194
                                    int maxrev)
25311
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
   195
{
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   196
	const char *data = index_deref(self, rev);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   197
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   198
	ps[0] = getbe32(data + 24);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   199
	ps[1] = getbe32(data + 28);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   200
25810
82d6a35cf432 parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents: 25584
diff changeset
   201
	/* 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
   202
	 * 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
   203
	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
   204
		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
   205
		return -1;
82d6a35cf432 parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents: 25584
diff changeset
   206
	}
82d6a35cf432 parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents: 25584
diff changeset
   207
	return 0;
25311
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
   208
}
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
   209
40861
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
   210
/*
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
   211
 * 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
   212
 *
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
   213
 * 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
   214
 * 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
   215
 *
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
   216
 * 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
   217
 */
44467
9db11679f8ac cext: make HgRevlogIndex_GetParents private again
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44066
diff changeset
   218
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
   219
{
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
   220
	int tiprev;
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
   221
	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
   222
		PyErr_BadInternalCall();
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
   223
		return -1;
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
   224
	}
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
   225
	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
   226
	if (rev < -1 || rev > tiprev) {
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
   227
		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
   228
		return -1;
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
   229
	} else if (rev == -1) {
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
   230
		ps[0] = ps[1] = -1;
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
   231
		return 0;
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
   232
	} else {
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
   233
		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
   234
	}
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
   235
}
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
   236
40703
d5b300ec2e89 sparse-revlog: add a `index_get_start` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40598
diff changeset
   237
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
   238
{
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   239
	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
   240
	uint64_t offset;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   241
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   242
	if (rev == nullrev)
40961
b54727f82511 sparse-revlog: handle nullrev in index_get_start
Boris Feld <boris.feld@octobus.net>
parents: 40960
diff changeset
   243
		return 0;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   244
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   245
	data = index_deref(self, rev);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   246
	offset = getbe32(data + 4);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   247
	if (rev == 0) {
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   248
		/* mask out version number for the first entry */
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   249
		offset &= 0xFFFF;
40703
d5b300ec2e89 sparse-revlog: add a `index_get_start` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40598
diff changeset
   250
	} else {
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   251
		uint32_t offset_high = getbe32(data);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   252
		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
   253
	}
d5b300ec2e89 sparse-revlog: add a `index_get_start` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40598
diff changeset
   254
	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
   255
}
d5b300ec2e89 sparse-revlog: add a `index_get_start` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40598
diff changeset
   256
40704
7da3729d4b45 sparse-revlog: add a `index_get_length` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40703
diff changeset
   257
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
   258
{
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   259
	const char *data;
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   260
	int tmp;
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   261
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   262
	if (rev == nullrev)
40962
c6939b353ebd sparse-revlog: handle nullrev in index_get_length
Boris Feld <boris.feld@octobus.net>
parents: 40961
diff changeset
   263
		return 0;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   264
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   265
	data = index_deref(self, rev);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   266
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   267
	tmp = (int)getbe32(data + 8);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   268
	if (tmp < 0) {
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   269
		PyErr_Format(PyExc_OverflowError,
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   270
		             "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
   271
		return -1;
40962
c6939b353ebd sparse-revlog: handle nullrev in index_get_length
Boris Feld <boris.feld@octobus.net>
parents: 40961
diff changeset
   272
	}
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   273
	return tmp;
40704
7da3729d4b45 sparse-revlog: add a `index_get_length` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40703
diff changeset
   274
}
25311
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
   275
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   276
/*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   277
 * 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
   278
 *    6 bytes: offset
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   279
 *    2 bytes: flags
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   280
 *    4 bytes: compressed length
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   281
 *    4 bytes: uncompressed length
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   282
 *    4 bytes: base revision
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   283
 *    4 bytes: link revision
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   284
 *    4 bytes: parent 1 revision
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   285
 *    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
   286
 *   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
   287
 */
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   288
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
   289
{
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   290
	uint64_t offset_flags, sidedata_offset;
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   291
	int comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2,
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   292
	    sidedata_comp_len;
7154
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   293
	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
   294
	const char *data;
38868
0db50770f388 index: don't add 1 to length variables
Martin von Zweigbergk <martinvonz@google.com>
parents: 38867
diff changeset
   295
	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
   296
40960
43974cd44967 revlog: introduce a constant for nullrev in `revlog.c`
Boris Feld <boris.feld@octobus.net>
parents: 40862
diff changeset
   297
	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
   298
		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
   299
		return self->nullentry;
38847
f3d394ea17db index: handle index[-1] as nullid more explicitly
Martin von Zweigbergk <martinvonz@google.com>
parents: 38846
diff changeset
   300
	}
f3d394ea17db index: handle index[-1] as nullid more explicitly
Martin von Zweigbergk <martinvonz@google.com>
parents: 38846
diff changeset
   301
38868
0db50770f388 index: don't add 1 to length variables
Martin von Zweigbergk <martinvonz@google.com>
parents: 38867
diff changeset
   302
	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
   303
		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
   304
		return NULL;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   305
	}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   306
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   307
	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
   308
	if (data == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   309
		return NULL;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   310
16437
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
   311
	offset_flags = getbe32(data + 4);
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   312
	/*
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   313
	 * The first entry on-disk needs the version number masked out,
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   314
	 * but this doesn't apply if entries are added to an empty index.
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   315
	 */
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   316
	if (self->length && pos == 0)
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   317
		offset_flags &= 0xFFFF;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   318
	else {
16437
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
   319
		uint32_t offset_high = getbe32(data);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   320
		offset_flags |= ((uint64_t)offset_high) << 32;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   321
	}
7154
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   322
16437
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
   323
	comp_len = getbe32(data + 8);
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
   324
	uncomp_len = getbe32(data + 12);
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
   325
	base_rev = getbe32(data + 16);
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
   326
	link_rev = getbe32(data + 20);
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
   327
	parent_1 = getbe32(data + 24);
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
   328
	parent_2 = getbe32(data + 28);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   329
	c_node_id = data + 32;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   330
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   331
	if (self->hdrsize == v1_hdrsize) {
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   332
		return Py_BuildValue(v1_tuple_format, offset_flags, comp_len,
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   333
		                     uncomp_len, base_rev, link_rev, parent_1,
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   334
		                     parent_2, c_node_id, self->nodelen);
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   335
	} else {
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   336
		sidedata_offset = getbe64(data + 64);
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   337
		sidedata_comp_len = getbe32(data + 72);
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   338
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   339
		return Py_BuildValue(v2_tuple_format, offset_flags, comp_len,
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   340
		                     uncomp_len, base_rev, link_rev, parent_1,
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   341
		                     parent_2, c_node_id, self->nodelen,
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   342
		                     sidedata_offset, sidedata_comp_len);
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   343
	}
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   344
}
47034
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   345
/*
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   346
 * 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
   347
 */
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   348
static PyObject *index_entry_binary(indexObject *self, PyObject *args)
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   349
{
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   350
	long rev;
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   351
	int header;
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   352
	const char *data;
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   353
	char entry[v2_hdrsize];
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   354
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   355
	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
   356
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   357
	if (!PyArg_ParseTuple(args, "lI", &rev, &header)) {
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   358
		return NULL;
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   359
	}
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   360
	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
   361
		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
   362
		             rev);
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   363
		return NULL;
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   364
	};
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   365
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   366
	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
   367
	if (data == NULL)
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   368
		return NULL;
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   369
	if (rev == 0) {
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   370
		// put the header at the start of the first entry
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   371
		memcpy(entry, data, self->hdrsize);
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   372
		putbe32(header, entry);
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   373
		return PyBytes_FromStringAndSize(entry, self->hdrsize);
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   374
	}
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   375
	return PyBytes_FromStringAndSize(data, self->hdrsize);
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   376
}
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   377
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   378
/*
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
   379
 * 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
   380
 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   381
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
   382
{
38868
0db50770f388 index: don't add 1 to length variables
Martin von Zweigbergk <martinvonz@google.com>
parents: 38867
diff changeset
   383
	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
   384
	const char *data;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   385
40960
43974cd44967 revlog: introduce a constant for nullrev in `revlog.c`
Boris Feld <boris.feld@octobus.net>
parents: 40862
diff changeset
   386
	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
   387
		return nullid;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   388
38868
0db50770f388 index: don't add 1 to length variables
Martin von Zweigbergk <martinvonz@google.com>
parents: 38867
diff changeset
   389
	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
   390
		return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   391
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   392
	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
	return data ? data + 32 : NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   394
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   395
37860
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
   396
/*
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
   397
 * 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
   398
 * 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
   399
 */
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
   400
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
   401
{
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
   402
	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
   403
	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
   404
		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
   405
		             (int)pos);
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
   406
	}
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
   407
	return node;
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
   408
}
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
   409
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
   410
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
   411
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
   412
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
   413
{
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
   414
	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
   415
	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
   416
		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
   417
	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
   418
		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
   419
	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
   420
	             thisnodelen, nodelen);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   421
	return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   422
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   423
38850
6104b203bec8 index: replace insert(-1, e) method by append(e) method
Martin von Zweigbergk <martinvonz@google.com>
parents: 38848
diff changeset
   424
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
   425
{
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   426
	uint64_t offset_flags, sidedata_offset;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   427
	int rev, comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2;
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   428
	Py_ssize_t c_node_id_len, sidedata_comp_len;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   429
	const char *c_node_id;
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   430
	char *data;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   431
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   432
	if (self->hdrsize == v1_hdrsize) {
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   433
		if (!PyArg_ParseTuple(obj, v1_tuple_format, &offset_flags,
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   434
		                      &comp_len, &uncomp_len, &base_rev,
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   435
		                      &link_rev, &parent_1, &parent_2,
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   436
		                      &c_node_id, &c_node_id_len)) {
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   437
			PyErr_SetString(PyExc_TypeError, "8-tuple required");
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   438
			return NULL;
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   439
		}
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   440
	} else {
46875
651e6df2b0a4 clang-format: run the formatter on mercurial/cext/revlog.c
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
   441
		if (!PyArg_ParseTuple(obj, v2_tuple_format, &offset_flags,
651e6df2b0a4 clang-format: run the formatter on mercurial/cext/revlog.c
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
   442
		                      &comp_len, &uncomp_len, &base_rev,
651e6df2b0a4 clang-format: run the formatter on mercurial/cext/revlog.c
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
   443
		                      &link_rev, &parent_1, &parent_2,
651e6df2b0a4 clang-format: run the formatter on mercurial/cext/revlog.c
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
   444
		                      &c_node_id, &c_node_id_len,
651e6df2b0a4 clang-format: run the formatter on mercurial/cext/revlog.c
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
   445
		                      &sidedata_offset, &sidedata_comp_len)) {
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   446
			PyErr_SetString(PyExc_TypeError, "10-tuple required");
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   447
			return NULL;
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   448
		}
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   449
	}
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   450
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
   451
	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
   452
		PyErr_SetString(PyExc_TypeError, "invalid node");
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   453
		return NULL;
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   454
	}
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   455
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   456
	if (self->new_length == self->added_length) {
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   457
		size_t new_added_length =
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   458
		    self->added_length ? self->added_length * 2 : 4096;
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   459
		void *new_added = PyMem_Realloc(self->added, new_added_length *
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   460
		                                                 self->hdrsize);
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   461
		if (!new_added)
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   462
			return PyErr_NoMemory();
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   463
		self->added = new_added;
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   464
		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
   465
	}
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   466
	rev = self->length + self->new_length;
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   467
	data = self->added + self->hdrsize * self->new_length++;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   468
	putbe32(offset_flags >> 32, data);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   469
	putbe32(offset_flags & 0xffffffffU, data + 4);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   470
	putbe32(comp_len, data + 8);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   471
	putbe32(uncomp_len, data + 12);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   472
	putbe32(base_rev, data + 16);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   473
	putbe32(link_rev, data + 20);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   474
	putbe32(parent_1, data + 24);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   475
	putbe32(parent_2, data + 28);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   476
	memcpy(data + 32, c_node_id, c_node_id_len);
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   477
	/* Padding since SHA-1 is only 20 bytes for now */
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   478
	memset(data + 32 + c_node_id_len, 0, 32 - c_node_id_len);
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   479
	if (self->hdrsize != v1_hdrsize) {
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   480
		putbe64(sidedata_offset, data + 64);
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   481
		putbe32(sidedata_comp_len, data + 72);
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   482
		/* Padding for 96 bytes alignment */
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   483
		memset(data + 76, 0, self->hdrsize - 76);
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
   484
	}
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
   485
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
   486
	if (self->ntinitialized)
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   487
		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
   488
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   489
	Py_CLEAR(self->headrevs);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   490
	Py_RETURN_NONE;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   491
}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   492
46717
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   493
/* 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
   494
   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
   495
   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
   496
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
   497
{
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   498
	uint64_t sidedata_offset;
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   499
	int rev;
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   500
	Py_ssize_t sidedata_comp_len;
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   501
	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
   502
#if LONG_MAX == 0x7fffffffL
651e6df2b0a4 clang-format: run the formatter on mercurial/cext/revlog.c
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
   503
	const char *const sidedata_format = PY23("nKi", "nKi");
651e6df2b0a4 clang-format: run the formatter on mercurial/cext/revlog.c
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
   504
#else
651e6df2b0a4 clang-format: run the formatter on mercurial/cext/revlog.c
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
   505
	const char *const sidedata_format = PY23("nki", "nki");
651e6df2b0a4 clang-format: run the formatter on mercurial/cext/revlog.c
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
   506
#endif
46717
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   507
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   508
	if (self->hdrsize == v1_hdrsize || self->inlined) {
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   509
		/*
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   510
		 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
   511
	   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
   512
	   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
   513
	   See issue6485.
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   514
	  */
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   515
		raise_revlog_error();
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   516
		return NULL;
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   517
	}
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   518
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   519
	if (!PyArg_ParseTuple(args, sidedata_format, &rev, &sidedata_offset,
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   520
	                      &sidedata_comp_len))
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   521
		return NULL;
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   522
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   523
	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
   524
		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
   525
		return NULL;
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   526
	}
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   527
	if (rev < self->length) {
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   528
		PyErr_SetString(
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   529
		    PyExc_IndexError,
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   530
		    "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
   531
		return NULL;
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   532
	}
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   533
46875
651e6df2b0a4 clang-format: run the formatter on mercurial/cext/revlog.c
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
   534
	/* 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
   535
	 */
46717
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   536
	data = self->added + self->hdrsize * (rev - self->length);
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   537
	putbe64(sidedata_offset, data + 64);
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   538
	putbe32(sidedata_comp_len, data + 72);
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   539
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   540
	Py_RETURN_NONE;
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   541
}
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
   542
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   543
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
   544
{
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   545
	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
   546
	PyObject *s = NULL;
23948
bd307b462ce2 parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents: 23947
diff changeset
   547
	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
   548
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   549
	if (obj == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   550
		return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   551
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   552
#define istat(__n, __d)                                                        \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   553
	do {                                                                   \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   554
		s = PyBytes_FromString(__d);                                   \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   555
		t = PyInt_FromSsize_t(self->__n);                              \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   556
		if (!s || !t)                                                  \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   557
			goto bail;                                             \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   558
		if (PyDict_SetItem(obj, s, t) == -1)                           \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   559
			goto bail;                                             \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   560
		Py_CLEAR(s);                                                   \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   561
		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
   562
	} while (0)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   563
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   564
	if (self->added_length)
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
   565
		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
   566
	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
   567
	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
   568
	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
   569
	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
   570
	if (self->ntinitialized) {
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
   571
		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
   572
		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
   573
		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
   574
		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
   575
	}
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   576
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   577
#undef istat
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   578
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   579
	return obj;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   580
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   581
bail:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   582
	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
   583
	Py_XDECREF(s);
23948
bd307b462ce2 parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents: 23947
diff changeset
   584
	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
   585
	return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   586
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   587
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   588
/*
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   589
 * 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
   590
 * the cached copy.
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   591
 */
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   592
static PyObject *list_copy(PyObject *list)
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   593
{
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   594
	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
   595
	PyObject *newlist = PyList_New(len);
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   596
	Py_ssize_t i;
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   597
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   598
	if (newlist == NULL)
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   599
		return NULL;
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   600
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   601
	for (i = 0; i < len; i++) {
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   602
		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
   603
		Py_INCREF(obj);
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   604
		PyList_SET_ITEM(newlist, i, obj);
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   605
	}
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   606
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   607
	return newlist;
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   608
}
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   609
34440
7ed0750c71a1 cext: wrap before brace for functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34438
diff changeset
   610
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
   611
{
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   612
	if (filter) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   613
		PyObject *arglist, *result;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   614
		int isfiltered;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   615
26107
50582df9d7a7 parsers: fix two cases of unsigned long instead of Py_ssize_t
Augie Fackler <augie@google.com>
parents: 26098
diff changeset
   616
		arglist = Py_BuildValue("(n)", arg);
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   617
		if (!arglist) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   618
			return -1;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   619
		}
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   620
46260
abba2d365373 revlog: migrate from PyEval_CallObject to PyObject_Call
Augie Fackler <augie@google.com>
parents: 46224
diff changeset
   621
		result = PyObject_Call(filter, arglist, NULL);
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   622
		Py_DECREF(arglist);
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   623
		if (!result) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   624
			return -1;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   625
		}
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   626
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   627
		/* 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
   628
		 * 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
   629
		isfiltered = PyObject_IsTrue(result);
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   630
		Py_DECREF(result);
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   631
		return isfiltered;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   632
	} else {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   633
		return 0;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   634
	}
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   635
}
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   636
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
   637
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
   638
                                          int parent_2, Py_ssize_t i)
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
   639
{
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
   640
	if (parent_1 >= 0 && phases[parent_1] > phases[i])
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
   641
		phases[i] = phases[parent_1];
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
   642
	if (parent_2 >= 0 && phases[parent_2] > phases[i])
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
   643
		phases[i] = phases[parent_2];
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
   644
}
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
   645
26053
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
   646
static PyObject *reachableroots2(indexObject *self, PyObject *args)
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   647
{
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   648
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   649
	/* Input */
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   650
	long minroot;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   651
	PyObject *includepatharg = NULL;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   652
	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
   653
	/* heads and roots are lists */
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   654
	PyObject *heads = NULL;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   655
	PyObject *roots = NULL;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   656
	PyObject *reachable = NULL;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   657
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   658
	PyObject *val;
38851
781b2720d2ac index: don't include nullid in len()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38850
diff changeset
   659
	Py_ssize_t len = index_length(self);
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   660
	long revnum;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   661
	Py_ssize_t k;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   662
	Py_ssize_t i;
26042
2a3010ba6f52 reachableroots: give anonymous name to short-lived "numheads" variable
Yuya Nishihara <yuya@tcha.org>
parents: 26041
diff changeset
   663
	Py_ssize_t l;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   664
	int r;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   665
	int parents[2];
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   666
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   667
	/* Internal data structure:
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   668
	 * 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
   669
	 * lentovisit
40561
5c14bf0c5be3 revlog: add blank line in comment to help clang-format
Augie Fackler <augie@google.com>
parents: 40560
diff changeset
   670
	 *
26044
b3ad349d0e50 reachableroots: extend "revstates" to array of bit flags
Yuya Nishihara <yuya@tcha.org>
parents: 26043
diff changeset
   671
	 * 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
   672
	int *tovisit = NULL;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   673
	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
   674
	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
   675
	char *revstates = NULL;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   676
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   677
	/* Get arguments */
26009
bbb698697efc reachableroots: fix transposition of set and list types in PyArg_ParseTuple
Augie Fackler <augie@google.com>
parents: 26008
diff changeset
   678
	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
   679
	                      &PyList_Type, &roots, &PyBool_Type,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   680
	                      &includepatharg))
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   681
		goto bail;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   682
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   683
	if (includepatharg == Py_True)
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   684
		includepath = 1;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   685
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   686
	/* Initialize return set */
26055
607868eccaa7 reachableroots: return list of revisions instead of set
Yuya Nishihara <yuya@tcha.org>
parents: 26054
diff changeset
   687
	reachable = PyList_New(0);
607868eccaa7 reachableroots: return list of revisions instead of set
Yuya Nishihara <yuya@tcha.org>
parents: 26054
diff changeset
   688
	if (reachable == NULL)
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   689
		goto bail;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   690
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   691
	/* Initialize internal datastructures */
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   692
	tovisit = (int *)malloc((len + 1) * sizeof(int));
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   693
	if (tovisit == NULL) {
26008
59d57ea69ae6 reachableroots: consistently use short-form of PyErr_NoMemory()
Augie Fackler <augie@google.com>
parents: 26007
diff changeset
   694
		PyErr_NoMemory();
26016
c8d41c9c23c7 reachableroots: unify bail cases to raise exception correctly
Yuya Nishihara <yuya@tcha.org>
parents: 26015
diff changeset
   695
		goto bail;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   696
	}
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   697
26043
f2f0a3ab6e41 reachableroots: rename "seen" array to "revstates" for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 26042
diff changeset
   698
	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
   699
	if (revstates == NULL) {
26008
59d57ea69ae6 reachableroots: consistently use short-form of PyErr_NoMemory()
Augie Fackler <augie@google.com>
parents: 26007
diff changeset
   700
		PyErr_NoMemory();
26016
c8d41c9c23c7 reachableroots: unify bail cases to raise exception correctly
Yuya Nishihara <yuya@tcha.org>
parents: 26015
diff changeset
   701
		goto bail;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   702
	}
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   703
26053
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
   704
	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
   705
	for (i = 0; i < l; i++) {
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
   706
		revnum = PyInt_AsLong(PyList_GET_ITEM(roots, i));
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
   707
		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
   708
			goto bail;
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
   709
		/* 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
   710
		 * 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
   711
		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
   712
			continue;
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
   713
		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
   714
	}
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
   715
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   716
	/* 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
   717
	l = PyList_GET_SIZE(heads);
2a3010ba6f52 reachableroots: give anonymous name to short-lived "numheads" variable
Yuya Nishihara <yuya@tcha.org>
parents: 26041
diff changeset
   718
	for (i = 0; i < l; i++) {
26018
c6115c30a376 reachableroots: verify type of each item of heads argument
Yuya Nishihara <yuya@tcha.org>
parents: 26017
diff changeset
   719
		revnum = PyInt_AsLong(PyList_GET_ITEM(heads, i));
c6115c30a376 reachableroots: verify type of each item of heads argument
Yuya Nishihara <yuya@tcha.org>
parents: 26017
diff changeset
   720
		if (revnum == -1 && PyErr_Occurred())
c6115c30a376 reachableroots: verify type of each item of heads argument
Yuya Nishihara <yuya@tcha.org>
parents: 26017
diff changeset
   721
			goto bail;
26017
44705659da94 reachableroots: verify integer range of heads argument (issue4775)
Yuya Nishihara <yuya@tcha.org>
parents: 26016
diff changeset
   722
		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
   723
			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
   724
			goto bail;
44705659da94 reachableroots: verify integer range of heads argument (issue4775)
Yuya Nishihara <yuya@tcha.org>
parents: 26016
diff changeset
   725
		}
26044
b3ad349d0e50 reachableroots: extend "revstates" to array of bit flags
Yuya Nishihara <yuya@tcha.org>
parents: 26043
diff changeset
   726
		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
   727
			tovisit[lentovisit++] = (int)revnum;
26044
b3ad349d0e50 reachableroots: extend "revstates" to array of bit flags
Yuya Nishihara <yuya@tcha.org>
parents: 26043
diff changeset
   728
			revstates[revnum + 1] |= RS_SEEN;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   729
		}
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   730
	}
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   731
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   732
	/* Visit the tovisit list and find the reachable roots */
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   733
	k = 0;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   734
	while (k < lentovisit) {
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   735
		/* 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
   736
		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
   737
		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
   738
			revstates[revnum + 1] |= RS_REACHABLE;
26053
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
   739
			val = PyInt_FromLong(revnum);
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
   740
			if (val == NULL)
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
   741
				goto bail;
26058
e7fe0a12376c reachableroots: handle error of PyList_Append()
Yuya Nishihara <yuya@tcha.org>
parents: 26055
diff changeset
   742
			r = PyList_Append(reachable, val);
26053
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
   743
			Py_DECREF(val);
26058
e7fe0a12376c reachableroots: handle error of PyList_Append()
Yuya Nishihara <yuya@tcha.org>
parents: 26055
diff changeset
   744
			if (r < 0)
e7fe0a12376c reachableroots: handle error of PyList_Append()
Yuya Nishihara <yuya@tcha.org>
parents: 26055
diff changeset
   745
				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
   746
			if (includepath == 0)
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   747
				continue;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   748
		}
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   749
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   750
		/* 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
   751
		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
   752
			continue;
8da628be211b reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents: 26033
diff changeset
   753
		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
   754
		if (r < 0)
8da628be211b reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents: 26033
diff changeset
   755
			goto bail;
8da628be211b reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents: 26033
diff changeset
   756
		for (i = 0; i < 2; i++) {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   757
			if (!(revstates[parents[i] + 1] & RS_SEEN) &&
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   758
			    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
   759
				tovisit[lentovisit++] = parents[i];
26044
b3ad349d0e50 reachableroots: extend "revstates" to array of bit flags
Yuya Nishihara <yuya@tcha.org>
parents: 26043
diff changeset
   760
				revstates[parents[i] + 1] |= RS_SEEN;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   761
			}
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   762
		}
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   763
	}
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   764
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   765
	/* 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
   766
	 * and add them to the reachable set */
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   767
	if (includepath == 1) {
26080
83c9edcac05c reachableroots: silence warning of implicit integer narrowing issued by clang
Yuya Nishihara <yuya@tcha.org>
parents: 26079
diff changeset
   768
		long minidx = minroot;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   769
		if (minidx < 0)
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   770
			minidx = 0;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   771
		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
   772
			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
   773
				continue;
8da628be211b reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents: 26033
diff changeset
   774
			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
   775
			/* 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
   776
			 * index_get_parents */
8da628be211b reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents: 26033
diff changeset
   777
			if (r < 0)
8da628be211b reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents: 26033
diff changeset
   778
				goto bail;
26059
8779ce81ea80 reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents: 26058
diff changeset
   779
			if (((revstates[parents[0] + 1] |
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   780
			      revstates[parents[1] + 1]) &
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   781
			     RS_REACHABLE) &&
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   782
			    !(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
   783
				revstates[i + 1] |= RS_REACHABLE;
39074
acd23830bcd6 cext: fix most truncation warnings in revlog on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39073
diff changeset
   784
				val = PyInt_FromSsize_t(i);
26059
8779ce81ea80 reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents: 26058
diff changeset
   785
				if (val == NULL)
8779ce81ea80 reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents: 26058
diff changeset
   786
					goto bail;
8779ce81ea80 reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents: 26058
diff changeset
   787
				r = PyList_Append(reachable, val);
8779ce81ea80 reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents: 26058
diff changeset
   788
				Py_DECREF(val);
8779ce81ea80 reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents: 26058
diff changeset
   789
				if (r < 0)
8779ce81ea80 reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents: 26058
diff changeset
   790
					goto bail;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   791
			}
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   792
		}
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   793
	}
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   794
26043
f2f0a3ab6e41 reachableroots: rename "seen" array to "revstates" for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 26042
diff changeset
   795
	free(revstates);
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   796
	free(tovisit);
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   797
	return reachable;
26016
c8d41c9c23c7 reachableroots: unify bail cases to raise exception correctly
Yuya Nishihara <yuya@tcha.org>
parents: 26015
diff changeset
   798
bail:
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   799
	Py_XDECREF(reachable);
26043
f2f0a3ab6e41 reachableroots: rename "seen" array to "revstates" for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 26042
diff changeset
   800
	free(revstates);
26016
c8d41c9c23c7 reachableroots: unify bail cases to raise exception correctly
Yuya Nishihara <yuya@tcha.org>
parents: 26015
diff changeset
   801
	free(tovisit);
26010
2c03e521a0c5 reachableroots: return NULL if we're throwing an exception
Augie Fackler <augie@google.com>
parents: 26009
diff changeset
   802
	return NULL;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   803
}
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
   804
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   805
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
   806
                             char phase)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   807
{
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   808
	Py_ssize_t len = index_length(self);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   809
	PyObject *item;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   810
	PyObject *iterator;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   811
	int rev, minrev = -1;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   812
	char *node;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   813
45175
211063648b29 phases: fix error return with no exception from computephases()
Yuya Nishihara <yuya@tcha.org>
parents: 45173
diff changeset
   814
	if (!PySet_Check(roots)) {
211063648b29 phases: fix error return with no exception from computephases()
Yuya Nishihara <yuya@tcha.org>
parents: 45173
diff changeset
   815
		PyErr_SetString(PyExc_TypeError,
211063648b29 phases: fix error return with no exception from computephases()
Yuya Nishihara <yuya@tcha.org>
parents: 45173
diff changeset
   816
		                "roots must be a set of nodes");
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   817
		return -2;
45175
211063648b29 phases: fix error return with no exception from computephases()
Yuya Nishihara <yuya@tcha.org>
parents: 45173
diff changeset
   818
	}
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   819
	iterator = PyObject_GetIter(roots);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   820
	if (iterator == NULL)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   821
		return -2;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   822
	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
   823
		if (node_check(self->nodelen, item, &node) == -1)
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   824
			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
   825
		rev = index_find_node(self, node);
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   826
		/* null is implicitly public, so negative is invalid */
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   827
		if (rev < 0 || rev >= len)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   828
			goto failed;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   829
		phases[rev] = phase;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   830
		if (minrev == -1 || minrev > rev)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   831
			minrev = rev;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   832
		Py_DECREF(item);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   833
	}
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   834
	Py_DECREF(iterator);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   835
	return minrev;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   836
failed:
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   837
	Py_DECREF(iterator);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   838
	Py_DECREF(item);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   839
	return -2;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   840
}
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   841
25190
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
   842
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
   843
{
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   844
	/* 0: public (untracked), 1: draft, 2: secret, 32: archive,
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   845
	   96: internal */
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   846
	static const char trackedphases[] = {1, 2, 32, 96};
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   847
	PyObject *roots = Py_None;
45179
ba5e4b11d085 phases: rename variable used for owned dict of phasesets
Yuya Nishihara <yuya@tcha.org>
parents: 45178
diff changeset
   848
	PyObject *phasesetsdict = NULL;
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   849
	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
   850
	Py_ssize_t len = index_length(self);
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
   851
	char *phases = NULL;
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   852
	int minphaserev = -1, rev, i;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   853
	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
   854
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
   855
	if (!PyArg_ParseTuple(args, "O", &roots))
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   856
		return NULL;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   857
	if (roots == NULL || !PyDict_Check(roots)) {
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   858
		PyErr_SetString(PyExc_TypeError, "roots must be a dictionary");
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   859
		return NULL;
36623
a472a897c340 cext: fix computephasesmapsets() not to return without setting an exception
Yuya Nishihara <yuya@tcha.org>
parents: 36621
diff changeset
   860
	}
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
   861
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   862
	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
   863
	if (phases == NULL) {
ad1cc1435b13 parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents: 27341
diff changeset
   864
		PyErr_NoMemory();
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   865
		return NULL;
27364
ad1cc1435b13 parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents: 27341
diff changeset
   866
	}
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   867
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   868
	for (i = 0; i < numphases; ++i) {
45180
a6fde9d789d9 phases: move short-lived PyObject pointers to local scope
Yuya Nishihara <yuya@tcha.org>
parents: 45179
diff changeset
   869
		PyObject *pyphase = PyInt_FromLong(trackedphases[i]);
a6fde9d789d9 phases: move short-lived PyObject pointers to local scope
Yuya Nishihara <yuya@tcha.org>
parents: 45179
diff changeset
   870
		PyObject *phaseroots = NULL;
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   871
		if (pyphase == NULL)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   872
			goto release;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   873
		phaseroots = PyDict_GetItem(roots, pyphase);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   874
		Py_DECREF(pyphase);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   875
		if (phaseroots == NULL)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   876
			continue;
45176
3264d58e8b06 phases: fix clang-format error
Yuya Nishihara <yuya@tcha.org>
parents: 45175
diff changeset
   877
		rev = add_roots_get_min(self, phaseroots, phases,
3264d58e8b06 phases: fix clang-format error
Yuya Nishihara <yuya@tcha.org>
parents: 45175
diff changeset
   878
		                        trackedphases[i]);
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   879
		if (rev == -2)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   880
			goto release;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   881
		if (rev != -1 && (minphaserev == -1 || rev < minphaserev))
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   882
			minphaserev = rev;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   883
	}
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   884
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   885
	for (i = 0; i < numphases; ++i) {
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   886
		phasesets[i] = PySet_New(NULL);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   887
		if (phasesets[i] == NULL)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   888
			goto release;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   889
	}
25190
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
   890
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   891
	if (minphaserev == -1)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   892
		minphaserev = len;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   893
	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
   894
		PyObject *pyphase = NULL;
a6fde9d789d9 phases: move short-lived PyObject pointers to local scope
Yuya Nishihara <yuya@tcha.org>
parents: 45179
diff changeset
   895
		PyObject *pyrev = NULL;
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   896
		int parents[2];
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   897
		/*
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   898
		 * The parent lookup could be skipped for phaseroots, but
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   899
		 * phase --force would historically not recompute them
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   900
		 * correctly, leaving descendents with a lower phase around.
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   901
		 * As such, unconditionally recompute the phase.
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   902
		 */
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   903
		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
   904
			goto release;
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   905
		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
   906
		switch (phases[rev]) {
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   907
		case 0:
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   908
			continue;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   909
		case 1:
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   910
			pyphase = phasesets[0];
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   911
			break;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   912
		case 2:
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   913
			pyphase = phasesets[1];
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   914
			break;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   915
		case 32:
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   916
			pyphase = phasesets[2];
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   917
			break;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   918
		case 96:
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   919
			pyphase = phasesets[3];
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   920
			break;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   921
		default:
45177
03332e5f67e9 phases: make sure an exception should be set on error return
Yuya Nishihara <yuya@tcha.org>
parents: 45176
diff changeset
   922
			/* 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
   923
			 * 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
   924
			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
   925
			                "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
   926
			goto release;
36623
a472a897c340 cext: fix computephasesmapsets() not to return without setting an exception
Yuya Nishihara <yuya@tcha.org>
parents: 36621
diff changeset
   927
		}
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   928
		pyrev = PyInt_FromLong(rev);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   929
		if (pyrev == NULL)
27364
ad1cc1435b13 parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents: 27341
diff changeset
   930
			goto release;
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   931
		if (PySet_Add(pyphase, pyrev) == -1) {
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   932
			Py_DECREF(pyrev);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   933
			goto release;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   934
		}
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   935
		Py_DECREF(pyrev);
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
   936
	}
45179
ba5e4b11d085 phases: rename variable used for owned dict of phasesets
Yuya Nishihara <yuya@tcha.org>
parents: 45178
diff changeset
   937
ba5e4b11d085 phases: rename variable used for owned dict of phasesets
Yuya Nishihara <yuya@tcha.org>
parents: 45178
diff changeset
   938
	phasesetsdict = _dict_new_presized(numphases);
ba5e4b11d085 phases: rename variable used for owned dict of phasesets
Yuya Nishihara <yuya@tcha.org>
parents: 45178
diff changeset
   939
	if (phasesetsdict == NULL)
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   940
		goto release;
45141
9719e118e4af cext: remove unused variables
Joerg Sonnenberger <joerg@bec.de>
parents: 45131
diff changeset
   941
	for (i = 0; i < numphases; ++i) {
45180
a6fde9d789d9 phases: move short-lived PyObject pointers to local scope
Yuya Nishihara <yuya@tcha.org>
parents: 45179
diff changeset
   942
		PyObject *pyphase = PyInt_FromLong(trackedphases[i]);
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   943
		if (pyphase == NULL)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   944
			goto release;
45179
ba5e4b11d085 phases: rename variable used for owned dict of phasesets
Yuya Nishihara <yuya@tcha.org>
parents: 45178
diff changeset
   945
		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
   946
		    -1) {
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   947
			Py_DECREF(pyphase);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   948
			goto release;
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
   949
		}
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   950
		Py_DECREF(phasesets[i]);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   951
		phasesets[i] = NULL;
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
   952
	}
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   953
45179
ba5e4b11d085 phases: rename variable used for owned dict of phasesets
Yuya Nishihara <yuya@tcha.org>
parents: 45178
diff changeset
   954
	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
   955
27364
ad1cc1435b13 parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents: 27341
diff changeset
   956
release:
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   957
	for (i = 0; i < numphases; ++i)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   958
		Py_XDECREF(phasesets[i]);
45179
ba5e4b11d085 phases: rename variable used for owned dict of phasesets
Yuya Nishihara <yuya@tcha.org>
parents: 45178
diff changeset
   959
	Py_XDECREF(phasesetsdict);
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   960
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
   961
	free(phases);
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
   962
	return NULL;
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
   963
}
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
   964
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   965
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
   966
{
25297
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
   967
	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
   968
	char *nothead = NULL;
22540
9a860ac8c216 parsers: fix uninitialize variable warning
David Soria Parra <davidsp@fb.com>
parents: 22484
diff changeset
   969
	PyObject *heads = NULL;
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   970
	PyObject *filter = NULL;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   971
	PyObject *filteredrevs = Py_None;
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
   972
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   973
	if (!PyArg_ParseTuple(args, "|O", &filteredrevs)) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   974
		return NULL;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   975
	}
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   976
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   977
	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
   978
		return list_copy(self->headrevs);
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   979
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   980
	Py_DECREF(self->filteredrevs);
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   981
	self->filteredrevs = filteredrevs;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   982
	Py_INCREF(filteredrevs);
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   983
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   984
	if (filteredrevs != Py_None) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   985
		filter = PyObject_GetAttrString(filteredrevs, "__contains__");
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   986
		if (!filter) {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   987
			PyErr_SetString(
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   988
			    PyExc_TypeError,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
   989
			    "filteredrevs has no attribute __contains__");
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   990
			goto bail;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   991
		}
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   992
	}
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   993
38851
781b2720d2ac index: don't include nullid in len()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38850
diff changeset
   994
	len = index_length(self);
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
   995
	heads = PyList_New(0);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
   996
	if (heads == NULL)
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
   997
		goto bail;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
   998
	if (len == 0) {
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
   999
		PyObject *nullid = PyInt_FromLong(-1);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1000
		if (nullid == NULL || PyList_Append(heads, nullid) == -1) {
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1001
			Py_XDECREF(nullid);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1002
			goto bail;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1003
		}
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1004
		goto done;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1005
	}
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1006
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1007
	nothead = calloc(len, 1);
27366
7e8a883da171 parsers: add a missed PyErr_NoMemory
Bryan O'Sullivan <bos@serpentine.com>
parents: 27365
diff changeset
  1008
	if (nothead == NULL) {
7e8a883da171 parsers: add a missed PyErr_NoMemory
Bryan O'Sullivan <bos@serpentine.com>
parents: 27365
diff changeset
  1009
		PyErr_NoMemory();
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1010
		goto bail;
27366
7e8a883da171 parsers: add a missed PyErr_NoMemory
Bryan O'Sullivan <bos@serpentine.com>
parents: 27365
diff changeset
  1011
	}
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1012
28386
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
  1013
	for (i = len - 1; i >= 0; i--) {
25297
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
  1014
		int isfiltered;
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
  1015
		int parents[2];
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1016
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1017
		/* 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
  1018
		 * 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
  1019
		 * 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
  1020
		 */
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
  1021
		if (nothead[i] != 1) {
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
  1022
			isfiltered = check_filter(filter, i);
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
  1023
			if (isfiltered == -1) {
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
  1024
				PyErr_SetString(PyExc_TypeError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1025
				                "unable to check filter");
28386
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
  1026
				goto bail;
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
  1027
			}
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
  1028
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
  1029
			if (isfiltered) {
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
  1030
				nothead[i] = 1;
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
  1031
				continue;
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
  1032
			}
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1033
		}
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1034
25860
895f04955a49 parsers: silence warning of implicit integer conversion issued by clang
Yuya Nishihara <yuya@tcha.org>
parents: 25810
diff changeset
  1035
		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
  1036
			goto bail;
25297
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
  1037
		for (j = 0; j < 2; j++) {
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
  1038
			if (parents[j] >= 0)
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
  1039
				nothead[parents[j]] = 1;
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1040
		}
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1041
	}
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1042
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1043
	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
  1044
		PyObject *head;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1045
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1046
		if (nothead[i])
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1047
			continue;
22400
888bc106de83 parsers: fix typing issue when constructing Python integer object
Henrik Stuart <hg@hstuart.dk>
parents: 22399
diff changeset
  1048
		head = PyInt_FromSsize_t(i);
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1049
		if (head == NULL || PyList_Append(heads, head) == -1) {
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1050
			Py_XDECREF(head);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1051
			goto bail;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1052
		}
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1053
	}
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1054
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1055
done:
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1056
	self->headrevs = heads;
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1057
	Py_XDECREF(filter);
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1058
	free(nothead);
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1059
	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
  1060
bail:
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1061
	Py_XDECREF(filter);
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1062
	Py_XDECREF(heads);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1063
	free(nothead);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1064
	return NULL;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1065
}
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1066
33174
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
  1067
/**
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
  1068
 * 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
  1069
 *
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
  1070
 * 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
  1071
 */
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1072
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
  1073
{
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1074
	const char *data;
41018
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
  1075
	int result;
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1076
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  1077
	data = index_deref(self, rev);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  1078
	if (data == NULL)
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  1079
		return -2;
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  1080
	result = getbe32(data + 16);
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1081
41018
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
  1082
	if (result > rev) {
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
  1083
		PyErr_Format(
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
  1084
		    PyExc_ValueError,
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
  1085
		    "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
  1086
		    rev, result);
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
  1087
		return -2;
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
  1088
	}
41019
7542466b94e2 revlog: cache delta base value under -1
Boris Feld <boris.feld@octobus.net>
parents: 41018
diff changeset
  1089
	if (result < -1) {
7542466b94e2 revlog: cache delta base value under -1
Boris Feld <boris.feld@octobus.net>
parents: 41018
diff changeset
  1090
		PyErr_Format(
7542466b94e2 revlog: cache delta base value under -1
Boris Feld <boris.feld@octobus.net>
parents: 41018
diff changeset
  1091
		    PyExc_ValueError,
41283
4948b327d3b9 cext: clang-format new code coming from stable branch
Yuya Nishihara <yuya@tcha.org>
parents: 41129
diff changeset
  1092
		    "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
  1093
		    result);
41019
7542466b94e2 revlog: cache delta base value under -1
Boris Feld <boris.feld@octobus.net>
parents: 41018
diff changeset
  1094
		return -2;
7542466b94e2 revlog: cache delta base value under -1
Boris Feld <boris.feld@octobus.net>
parents: 41018
diff changeset
  1095
	}
41018
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
  1096
	return result;
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1097
}
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1098
41085
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1099
/**
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1100
 * 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
  1101
 *
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1102
 * Only relevant for sparse-revlog case.
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1103
 * 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
  1104
 */
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1105
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
  1106
{
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1107
	int ps[2];
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1108
	Py_ssize_t base;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1109
	while (rev >= 0) {
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1110
		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
  1111
		if (base == rev) {
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1112
			base = -1;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1113
		}
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1114
		if (base == -2) {
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1115
			assert(PyErr_Occurred());
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1116
			return -1;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1117
		}
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1118
		if (base == -1) {
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1119
			return 1;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1120
		}
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1121
		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
  1122
			assert(PyErr_Occurred());
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1123
			return -1;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1124
		};
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1125
		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
  1126
			return 0;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1127
		}
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1128
		rev = base;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1129
	}
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1130
	return rev == -1;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1131
}
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
  1132
41086
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
  1133
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
  1134
{
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
  1135
	long rev;
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
  1136
	int issnap;
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
  1137
	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
  1138
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
  1139
	if (!pylong_to_long(value, &rev)) {
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
  1140
		return NULL;
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
  1141
	}
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
  1142
	if (rev < -1 || rev >= length) {
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
  1143
		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
  1144
		             rev);
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
  1145
		return NULL;
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
  1146
	};
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
  1147
	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
  1148
	if (issnap < 0) {
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
  1149
		return NULL;
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
  1150
	};
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
  1151
	return PyBool_FromLong((long)issnap);
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
  1152
}
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
  1153
41108
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1154
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
  1155
{
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1156
	Py_ssize_t start_rev;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1157
	PyObject *cache;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1158
	Py_ssize_t base;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1159
	Py_ssize_t rev;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1160
	PyObject *key = NULL;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1161
	PyObject *value = NULL;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1162
	const Py_ssize_t length = index_length(self);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1163
	if (!PyArg_ParseTuple(args, "O!n", &PyDict_Type, &cache, &start_rev)) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1164
		return NULL;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1165
	}
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1166
	for (rev = start_rev; rev < length; rev++) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1167
		int issnap;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1168
		PyObject *allvalues = NULL;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1169
		issnap = index_issnapshotrev(self, rev);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1170
		if (issnap < 0) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1171
			goto bail;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1172
		}
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1173
		if (issnap == 0) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1174
			continue;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1175
		}
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1176
		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
  1177
		if (base == rev) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1178
			base = -1;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1179
		}
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1180
		if (base == -2) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1181
			assert(PyErr_Occurred());
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1182
			goto bail;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1183
		}
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1184
		key = PyInt_FromSsize_t(base);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1185
		allvalues = PyDict_GetItem(cache, key);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1186
		if (allvalues == NULL && PyErr_Occurred()) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1187
			goto bail;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1188
		}
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1189
		if (allvalues == NULL) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1190
			int r;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1191
			allvalues = PyList_New(0);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1192
			if (!allvalues) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1193
				goto bail;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1194
			}
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1195
			r = PyDict_SetItem(cache, key, allvalues);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1196
			Py_DECREF(allvalues);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1197
			if (r < 0) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1198
				goto bail;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1199
			}
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1200
		}
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1201
		value = PyInt_FromSsize_t(rev);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1202
		if (PyList_Append(allvalues, value)) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1203
			goto bail;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1204
		}
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1205
		Py_CLEAR(key);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1206
		Py_CLEAR(value);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1207
	}
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1208
	Py_RETURN_NONE;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1209
bail:
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1210
	Py_XDECREF(key);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1211
	Py_XDECREF(value);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1212
	return NULL;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1213
}
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  1214
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1215
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
  1216
{
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1217
	int rev, generaldelta;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1218
	PyObject *stoparg;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1219
	int stoprev, iterrev, baserev = -1;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1220
	int stopped;
33174
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
  1221
	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
  1222
	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
  1223
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1224
	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
  1225
		return NULL;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1226
	}
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1227
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1228
	if (PyInt_Check(stoparg)) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1229
		stoprev = (int)PyInt_AsLong(stoparg);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1230
		if (stoprev == -1 && PyErr_Occurred()) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1231
			return NULL;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1232
		}
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1233
	} else if (stoparg == Py_None) {
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1234
		stoprev = -2;
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1235
	} else {
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1236
		PyErr_SetString(PyExc_ValueError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1237
		                "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
  1238
		return NULL;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1239
	}
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1240
38868
0db50770f388 index: don't add 1 to length variables
Martin von Zweigbergk <martinvonz@google.com>
parents: 38867
diff changeset
  1241
	if (rev < 0 || rev >= length) {
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1242
		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
  1243
		return NULL;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1244
	}
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1245
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1246
	chain = PyList_New(0);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1247
	if (chain == NULL) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1248
		return NULL;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1249
	}
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1250
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1251
	baserev = index_baserev(self, rev);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1252
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1253
	/* This should never happen. */
33174
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
  1254
	if (baserev <= -2) {
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
  1255
		/* 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
  1256
		assert(PyErr_Occurred());
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1257
		goto bail;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1258
	}
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1259
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1260
	iterrev = rev;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1261
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1262
	while (iterrev != baserev && iterrev != stoprev) {
33174
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
  1263
		PyObject *value = PyInt_FromLong(iterrev);
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1264
		if (value == NULL) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1265
			goto bail;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1266
		}
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1267
		if (PyList_Append(chain, value)) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1268
			Py_DECREF(value);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1269
			goto bail;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1270
		}
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1271
		Py_DECREF(value);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1272
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1273
		if (generaldelta) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1274
			iterrev = baserev;
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1275
		} else {
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1276
			iterrev--;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1277
		}
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1278
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1279
		if (iterrev < 0) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1280
			break;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1281
		}
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1282
38868
0db50770f388 index: don't add 1 to length variables
Martin von Zweigbergk <martinvonz@google.com>
parents: 38867
diff changeset
  1283
		if (iterrev >= length) {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1284
			PyErr_SetString(PyExc_IndexError,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1285
			                "revision outside index");
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1286
			return NULL;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1287
		}
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1288
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1289
		baserev = index_baserev(self, iterrev);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1290
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1291
		/* This should never happen. */
33174
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
  1292
		if (baserev <= -2) {
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
  1293
			/* 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
  1294
			assert(PyErr_Occurred());
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1295
			goto bail;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1296
		}
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1297
	}
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1298
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1299
	if (iterrev == stoprev) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1300
		stopped = 1;
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1301
	} else {
33174
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
  1302
		PyObject *value = PyInt_FromLong(iterrev);
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1303
		if (value == NULL) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1304
			goto bail;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1305
		}
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1306
		if (PyList_Append(chain, value)) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1307
			Py_DECREF(value);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1308
			goto bail;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1309
		}
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1310
		Py_DECREF(value);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1311
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1312
		stopped = 0;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1313
	}
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1314
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1315
	if (PyList_Reverse(chain)) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1316
		goto bail;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1317
	}
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1318
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1319
	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
  1320
	Py_DECREF(chain);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1321
	return result;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1322
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1323
bail:
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1324
	Py_DECREF(chain);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1325
	return NULL;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1326
}
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
  1327
40705
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
  1328
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
  1329
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
  1330
{
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
  1331
	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
  1332
	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
  1333
	int end_size;
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
  1334
	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
  1335
	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
  1336
		return -1;
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
  1337
	}
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
  1338
	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
  1339
	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
  1340
		return -1;
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
  1341
	}
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
  1342
	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
  1343
	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
  1344
		return -1;
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
  1345
	}
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
  1346
	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
  1347
		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
  1348
		             "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
  1349
		             "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
  1350
		             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
  1351
		return -1;
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
  1352
	}
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
  1353
	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
  1354
}
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
  1355
40742
8edca70dc951 revlog: update the documentation for `trim_endidx`
Boris Feld <boris.feld@octobus.net>
parents: 40741
diff changeset
  1356
/* 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
  1357
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
  1358
                              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
  1359
{
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
  1360
	int length;
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
  1361
	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
  1362
		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
  1363
		if (length < 0) {
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
  1364
			return -1;
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
  1365
		}
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
  1366
		if (length != 0) {
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
  1367
			break;
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
  1368
		}
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
  1369
		endidx -= 1;
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
  1370
	}
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
  1371
	return endidx;
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
  1372
}
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
  1373
40707
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1374
struct Gap {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1375
	int64_t size;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1376
	Py_ssize_t idx;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1377
};
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1378
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1379
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
  1380
{
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1381
	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
  1382
	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
  1383
	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
  1384
		return -1;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1385
	} 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
  1386
		return 1;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1387
	}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1388
	return 0;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1389
}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1390
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
  1391
{
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1392
	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
  1393
	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
  1394
	if (l_left < l_right) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1395
		return -1;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1396
	} 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
  1397
		return 1;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1398
	}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1399
	return 0;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1400
}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1401
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1402
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
  1403
{
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1404
	/* method arguments */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1405
	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
  1406
	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
  1407
	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
  1408
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1409
	/* other core variables */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1410
	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
  1411
	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
  1412
	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
  1413
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1414
	/* 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
  1415
	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
  1416
	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
  1417
	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
  1418
	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
  1419
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1420
	/* 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
  1421
	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
  1422
	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
  1423
	int64_t previous_end;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1424
	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
  1425
	Py_ssize_t num_gaps =
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1426
	    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
  1427
	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
  1428
	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
  1429
	PyObject *chunk = NULL;              /* individual slice */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1430
	PyObject *allchunks = NULL;          /* all slices */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1431
	Py_ssize_t previdx;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1432
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1433
	/* parsing argument */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1434
	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
  1435
	                      &targetdensity, &mingapsize)) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1436
		goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1437
	}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1438
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1439
	/* 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
  1440
	 */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1441
	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
  1442
	if (num_revs <= 1) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1443
		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
  1444
		goto done;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1445
	}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1446
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1447
	/* 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
  1448
	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
  1449
	if (revs == NULL) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1450
		PyErr_NoMemory();
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1451
		goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1452
	}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1453
	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
  1454
		Py_ssize_t revnum = PyInt_AsLong(PyList_GET_ITEM(list_revs, i));
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1455
		if (revnum == -1 && PyErr_Occurred()) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1456
			goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1457
		}
40963
2e305e54eae3 sparse-revlog: protect C code against delta chain including nullrev
Boris Feld <boris.feld@octobus.net>
parents: 40962
diff changeset
  1458
		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
  1459
			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
  1460
			             "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
  1461
			goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1462
		}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1463
		revs[i] = revnum;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1464
	}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1465
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1466
	/* 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
  1467
	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
  1468
	if (deltachainspan < 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1469
		goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1470
	}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1471
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1472
	if (deltachainspan <= mingapsize) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1473
		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
  1474
		goto done;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1475
	}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1476
	chainpayload = 0;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1477
	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
  1478
		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
  1479
		if (tmp < 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1480
			goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1481
		}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1482
		chainpayload += tmp;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1483
	}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1484
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1485
	readdata = deltachainspan;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1486
	density = 1.0;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1487
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1488
	if (0 < deltachainspan) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1489
		density = (double)chainpayload / (double)deltachainspan;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1490
	}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1491
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1492
	if (density >= targetdensity) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1493
		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
  1494
		goto done;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1495
	}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1496
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1497
	/* 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
  1498
	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
  1499
	if (gaps == NULL) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1500
		PyErr_NoMemory();
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1501
		goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1502
	}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1503
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1504
	previous_end = -1;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1505
	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
  1506
		int64_t revstart;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1507
		int revsize;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1508
		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
  1509
		if (revstart < 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1510
			goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1511
		};
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1512
		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
  1513
		if (revsize < 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1514
			goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1515
		};
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1516
		if (revsize == 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1517
			continue;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1518
		}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1519
		if (previous_end >= 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1520
			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
  1521
			if (gapsize > mingapsize) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1522
				gaps[num_gaps].size = gapsize;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1523
				gaps[num_gaps].idx = i;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1524
				num_gaps += 1;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1525
			}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1526
		}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1527
		previous_end = revstart + revsize;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1528
	}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1529
	if (num_gaps == 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1530
		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
  1531
		goto done;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1532
	}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1533
	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
  1534
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1535
	/* 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
  1536
	selected_indices =
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1537
	    (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
  1538
	if (selected_indices == NULL) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1539
		PyErr_NoMemory();
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1540
		goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1541
	}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1542
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1543
	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
  1544
		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
  1545
		readdata -= gaps[i].size;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1546
		num_selected += 1;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1547
		if (readdata <= 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1548
			density = 1.0;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1549
		} else {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1550
			density = (double)chainpayload / (double)readdata;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1551
		}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1552
		if (density >= targetdensity) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1553
			break;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1554
		}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1555
	}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1556
	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
  1557
	      &Py_ssize_t_compare);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1558
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1559
	/* create the resulting slice */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1560
	allchunks = PyList_New(0);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1561
	if (allchunks == NULL) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1562
		goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1563
	}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1564
	previdx = 0;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1565
	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
  1566
	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
  1567
		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
  1568
		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
  1569
		if (endidx < 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1570
			goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1571
		}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1572
		if (previdx < endidx) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1573
			chunk = PyList_GetSlice(list_revs, previdx, endidx);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1574
			if (chunk == NULL) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1575
				goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1576
			}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1577
			if (PyList_Append(allchunks, chunk) == -1) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1578
				goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1579
			}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1580
			Py_DECREF(chunk);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1581
			chunk = NULL;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1582
		}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1583
		previdx = idx;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1584
	}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1585
	result = allchunks;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1586
	goto done;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1587
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1588
bail:
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1589
	Py_XDECREF(allchunks);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1590
	Py_XDECREF(chunk);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1591
done:
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1592
	free(revs);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1593
	free(gaps);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1594
	free(selected_indices);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1595
	return result;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1596
}
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  1597
16618
6bae941b58ad parsers: change the type of nt_level
Bryan O'Sullivan <bryano@fb.com>
parents: 16617
diff changeset
  1598
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
  1599
{
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1600
	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
  1601
	if (!(level & 1))
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1602
		v >>= 4;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1603
	return v & 0xf;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1604
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1605
16616
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
  1606
/*
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
  1607
 * Return values:
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
  1608
 *
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
  1609
 *   -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
  1610
 *   -2: not found
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
  1611
 * rest: valid rev
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
  1612
 */
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
  1613
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
  1614
                   int hex)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1615
{
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1616
	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
  1617
	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
  1618
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
  1619
	/* 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
  1620
	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
  1621
	    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
  1622
		return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1623
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1624
	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
  1625
		maxlevel = nodelen;
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1626
	else
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
  1627
		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
  1628
	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
  1629
		maxlevel = 2 * self->nodelen;
16641
e6dfbc5df76f parsers: use the correct maximum radix tree depth
Bryan O'Sullivan <bryano@fb.com>
parents: 16604
diff changeset
  1630
e6dfbc5df76f parsers: use the correct maximum radix tree depth
Bryan O'Sullivan <bryano@fb.com>
parents: 16604
diff changeset
  1631
	for (level = off = 0; level < maxlevel; level++) {
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1632
		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
  1633
		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
  1634
		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
  1635
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1636
		if (v < 0) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1637
			const char *n;
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1638
			Py_ssize_t i;
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1639
38846
f738c502e43b index: store nullrev as -1 in nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38845
diff changeset
  1640
			v = -(v + 2);
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
  1641
			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
  1642
			if (n == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1643
				return -2;
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1644
			for (i = level; i < maxlevel; i++)
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1645
				if (getnybble(node, i) != nt_level(n, i))
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1646
					return -2;
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1647
			return v;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1648
		}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1649
		if (v == 0)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1650
			return -2;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1651
		off = v;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1652
	}
16616
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
  1653
	/* 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
  1654
	return -4;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1655
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1656
38915
fff675dfb80b index: pass only nodetree to nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38914
diff changeset
  1657
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
  1658
{
38915
fff675dfb80b index: pass only nodetree to nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38914
diff changeset
  1659
	if (self->length == self->capacity) {
46224
fcc324a228fe revlog: use size_t for nodetree capacity
Jun Wu <quark@fb.com>
parents: 46144
diff changeset
  1660
		size_t newcapacity;
38938
dcd395dc98d8 index: remove side-effect from failed nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38937
diff changeset
  1661
		nodetreenode *newnodes;
39071
06ff7ea4f440 index: avoid duplicating capacity-growth expression
Martin von Zweigbergk <martinvonz@google.com>
parents: 39070
diff changeset
  1662
		newcapacity = self->capacity * 2;
46224
fcc324a228fe revlog: use size_t for nodetree capacity
Jun Wu <quark@fb.com>
parents: 46144
diff changeset
  1663
		if (newcapacity >= SIZE_MAX / sizeof(nodetreenode)) {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1664
			PyErr_SetString(PyExc_MemoryError,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1665
			                "overflow in nt_new");
24623
2262d7bc469e parsers: check for memory allocation overflows more carefully
Bryan O'Sullivan <bryano@fb.com>
parents: 24622
diff changeset
  1666
			return -1;
2262d7bc469e parsers: check for memory allocation overflows more carefully
Bryan O'Sullivan <bryano@fb.com>
parents: 24622
diff changeset
  1667
		}
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1668
		newnodes =
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1669
		    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
  1670
		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
  1671
			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
  1672
			return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1673
		}
38938
dcd395dc98d8 index: remove side-effect from failed nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38937
diff changeset
  1674
		self->capacity = newcapacity;
dcd395dc98d8 index: remove side-effect from failed nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38937
diff changeset
  1675
		self->nodes = newnodes;
38915
fff675dfb80b index: pass only nodetree to nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38914
diff changeset
  1676
		memset(&self->nodes[self->length], 0,
fff675dfb80b index: pass only nodetree to nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38914
diff changeset
  1677
		       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
  1678
	}
38915
fff675dfb80b index: pass only nodetree to nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38914
diff changeset
  1679
	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
  1680
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1681
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
  1682
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
  1683
{
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1684
	int level = 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1685
	int off = 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1686
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
  1687
	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
  1688
		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
  1689
		nodetreenode *n;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1690
		int v;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1691
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
  1692
		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
  1693
		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
  1694
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1695
		if (v == 0) {
38846
f738c502e43b index: store nullrev as -1 in nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38845
diff changeset
  1696
			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
  1697
			return 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1698
		}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1699
		if (v < 0) {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1700
			const char *oldnode =
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1701
			    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
  1702
			int noff;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1703
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
  1704
			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
  1705
				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
  1706
			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
  1707
				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
  1708
				return 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1709
			}
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
  1710
			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
  1711
			if (noff == -1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1712
				return -1;
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
  1713
			/* 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
  1714
			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
  1715
			off = noff;
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
  1716
			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
  1717
			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
  1718
			if (level > self->depth)
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
  1719
				self->depth = level;
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
  1720
			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
  1721
		} else {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1722
			level += 1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1723
			off = v;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1724
		}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1725
	}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1726
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1727
	return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1728
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1729
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  1730
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
  1731
{
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
  1732
	Py_ssize_t rev;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
  1733
	const char *node;
39227
42cc76d0f836 cext: fix revlog compiler error on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39226
diff changeset
  1734
	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
  1735
	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
  1736
		return NULL;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  1737
	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
  1738
	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
  1739
		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
  1740
		return NULL;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
  1741
	}
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  1742
	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
  1743
	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
  1744
		return NULL;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
  1745
	Py_RETURN_NONE;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
  1746
}
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
  1747
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
  1748
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
  1749
{
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1750
	/* 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
  1751
	 */
38846
f738c502e43b index: store nullrev as -1 in nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38845
diff changeset
  1752
	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
  1753
}
f9fc59ea3135 index: create function for deleting node from nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38821
diff changeset
  1754
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
  1755
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
  1756
{
39225
fcaffbd7e635 index: fix a comment about overflow-checking
Martin von Zweigbergk <martinvonz@google.com>
parents: 39219
diff changeset
  1757
	/* 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
  1758
	self->nodes = NULL;
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
  1759
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
  1760
	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
  1761
	/* 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
  1762
	 * 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
  1763
	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
  1764
	self->nodelen = index->nodelen;
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
  1765
	self->depth = 0;
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
  1766
	self->splits = 0;
46224
fcc324a228fe revlog: use size_t for nodetree capacity
Jun Wu <quark@fb.com>
parents: 46144
diff changeset
  1767
	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
  1768
		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
  1769
		return -1;
4dd92a15fcca index: move check for too large capacity into nt_init()
Martin von Zweigbergk <martinvonz@google.com>
parents: 39069
diff changeset
  1770
	}
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
  1771
	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
  1772
	if (self->nodes == NULL) {
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
  1773
		PyErr_NoMemory();
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
  1774
		return -1;
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
  1775
	}
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
  1776
	self->length = 1;
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
  1777
	return 0;
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
  1778
}
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
  1779
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  1780
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
  1781
{
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
  1782
	PyObject *index;
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
  1783
	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
  1784
	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
  1785
	                      &capacity))
39218
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
  1786
		return -1;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  1787
	Py_INCREF(index);
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1788
	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
  1789
}
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
  1790
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1791
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
  1792
{
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1793
	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
  1794
}
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1795
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1796
/*
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1797
 * 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
  1798
 *
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1799
 * Return values:
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1800
 *
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1801
 *   -3: error (exception set)
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1802
 *   -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
  1803
 * rest: length of shortest prefix
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1804
 */
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1805
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
  1806
{
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1807
	int level, off;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1808
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
  1809
	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
  1810
		int k, v;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1811
		nodetreenode *n = &self->nodes[off];
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1812
		k = nt_level(node, level);
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1813
		v = n->children[k];
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1814
		if (v < 0) {
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1815
			const char *n;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1816
			v = -(v + 2);
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1817
			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
  1818
			if (n == NULL)
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1819
				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
  1820
			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
  1821
				/*
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1822
				 * 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
  1823
				 * 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
  1824
				 * not exist).
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1825
				 */
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1826
				return -2;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1827
			return level + 1;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1828
		}
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1829
		if (v == 0)
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1830
			return -2;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1831
		off = v;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1832
	}
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1833
	/*
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1834
	 * 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
  1835
	 * 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
  1836
	 * 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
  1837
	 */
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1838
	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
  1839
	return -3;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1840
}
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
  1841
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  1842
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
  1843
{
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
  1844
	PyObject *val;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
  1845
	char *node;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
  1846
	int length;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
  1847
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
  1848
	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
  1849
		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
  1850
	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
  1851
		return NULL;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
  1852
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  1853
	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
  1854
	if (length == -3)
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
  1855
		return NULL;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
  1856
	if (length == -2) {
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
  1857
		raise_revlog_error();
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
  1858
		return NULL;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
  1859
	}
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
  1860
	return PyInt_FromLong(length);
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
  1861
}
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
  1862
39218
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
  1863
static void nt_dealloc(nodetree *self)
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
  1864
{
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
  1865
	free(self->nodes);
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
  1866
	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
  1867
}
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  1868
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  1869
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
  1870
{
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  1871
	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
  1872
	nt_dealloc(&self->nt);
39218
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
  1873
	PyObject_Del(self);
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
  1874
}
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
  1875
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  1876
static PyMethodDef ntobj_methods[] = {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1877
    {"insert", (PyCFunction)ntobj_insert, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1878
     "insert an index entry"},
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1879
    {"shortest", (PyCFunction)ntobj_shortest, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1880
     "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
  1881
    {NULL} /* Sentinel */
39226
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
  1882
};
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
  1883
39218
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
  1884
static PyTypeObject nodetreeType = {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1885
    PyVarObject_HEAD_INIT(NULL, 0) /* header */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1886
    "parsers.nodetree",            /* tp_name */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1887
    sizeof(nodetreeObject),        /* tp_basicsize */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1888
    0,                             /* tp_itemsize */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1889
    (destructor)ntobj_dealloc,     /* tp_dealloc */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1890
    0,                             /* tp_print */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1891
    0,                             /* tp_getattr */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1892
    0,                             /* tp_setattr */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1893
    0,                             /* tp_compare */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1894
    0,                             /* tp_repr */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1895
    0,                             /* tp_as_number */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1896
    0,                             /* tp_as_sequence */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1897
    0,                             /* tp_as_mapping */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1898
    0,                             /* tp_hash */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1899
    0,                             /* tp_call */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1900
    0,                             /* tp_str */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1901
    0,                             /* tp_getattro */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1902
    0,                             /* tp_setattro */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1903
    0,                             /* tp_as_buffer */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1904
    Py_TPFLAGS_DEFAULT,            /* tp_flags */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1905
    "nodetree",                    /* tp_doc */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1906
    0,                             /* tp_traverse */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1907
    0,                             /* tp_clear */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1908
    0,                             /* tp_richcompare */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1909
    0,                             /* tp_weaklistoffset */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1910
    0,                             /* tp_iter */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1911
    0,                             /* tp_iternext */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1912
    ntobj_methods,                 /* tp_methods */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1913
    0,                             /* tp_members */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1914
    0,                             /* tp_getset */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1915
    0,                             /* tp_base */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1916
    0,                             /* tp_dict */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1917
    0,                             /* tp_descr_get */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1918
    0,                             /* tp_descr_set */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1919
    0,                             /* tp_dictoffset */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1920
    (initproc)ntobj_init,          /* tp_init */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  1921
    0,                             /* tp_alloc */
39218
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
  1922
};
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
  1923
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
  1924
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
  1925
{
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  1926
	if (!self->ntinitialized) {
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  1927
		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
  1928
			nt_dealloc(&self->nt);
38912
d1bc0e7c862b index: extract a type for the nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38911
diff changeset
  1929
			return -1;
d1bc0e7c862b index: extract a type for the nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38911
diff changeset
  1930
		}
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  1931
		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
  1932
			nt_dealloc(&self->nt);
16615
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1933
			return -1;
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1934
		}
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  1935
		self->ntinitialized = 1;
38851
781b2720d2ac index: don't include nullid in len()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38850
diff changeset
  1936
		self->ntrev = (int)index_length(self);
16615
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1937
		self->ntlookups = 1;
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1938
		self->ntmisses = 0;
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1939
	}
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1940
	return 0;
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1941
}
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1942
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1943
/*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1944
 * Return values:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1945
 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1946
 *   -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
  1947
 *   -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
  1948
 * rest: valid rev
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1949
 */
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
  1950
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
  1951
{
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1952
	int rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1953
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
  1954
	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
  1955
		return -3;
44bbc89ec5e0 revlog: remove micro-optimization for looking up only nullid
Martin von Zweigbergk <martinvonz@google.com>
parents: 38819
diff changeset
  1956
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1957
	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
  1958
	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
  1959
	if (rev >= -1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1960
		return rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1961
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1962
	/*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1963
	 * 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
  1964
	 * 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
  1965
	 * 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
  1966
	 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1967
	 * 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
  1968
	 * 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
  1969
	 * 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
  1970
	 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1971
	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
  1972
		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
  1973
			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
  1974
			if (n == NULL)
37861
a9d9802d577e revlog: don't say "not found" on internal error
Martin von Zweigbergk <martinvonz@google.com>
parents: 37860
diff changeset
  1975
				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
  1976
			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
  1977
				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
  1978
					return -3;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1979
				break;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1980
			}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1981
		}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1982
	} else {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1983
		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
  1984
			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
  1985
			if (n == NULL)
a9d9802d577e revlog: don't say "not found" on internal error
Martin von Zweigbergk <martinvonz@google.com>
parents: 37860
diff changeset
  1986
				return -3;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  1987
			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
  1988
				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
  1989
				return -3;
16614
1d800eb9ba52 parsers: update ntrev when we stop scanning
Bryan O'Sullivan <bryano@fb.com>
parents: 16597
diff changeset
  1990
			}
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
  1991
			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
  1992
				break;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1993
			}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1994
		}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1995
		self->ntrev = rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1996
	}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1997
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1998
	if (rev >= 0)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1999
		return rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2000
	return -2;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2001
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2002
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2003
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
  2004
{
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2005
	char *node;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2006
	int rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2007
40598
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
  2008
	if (PyInt_Check(value)) {
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
  2009
		long idx;
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
  2010
		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
  2011
			return NULL;
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
  2012
		}
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
  2013
		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
  2014
	}
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2015
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
  2016
	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
  2017
		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
  2018
	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
  2019
	if (rev >= -1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2020
		return PyInt_FromLong(rev);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2021
	if (rev == -2)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2022
		raise_revlog_error();
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2023
	return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2024
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2025
37929
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
  2026
/*
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
  2027
 * 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
  2028
 */
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2029
static int index_populate_nt(indexObject *self)
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2030
{
37929
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
  2031
	int rev;
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
  2032
	if (self->ntrev > 0) {
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
  2033
		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
  2034
			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
  2035
			if (n == NULL)
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
  2036
				return -1;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  2037
			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
  2038
				return -1;
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
  2039
		}
37930
892592475094 revlog: use literal -1 instead of variable that always has that value
Martin von Zweigbergk <martinvonz@google.com>
parents: 37929
diff changeset
  2040
		self->ntrev = -1;
37929
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
  2041
	}
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
  2042
	return 0;
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
  2043
}
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
  2044
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2045
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
  2046
{
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2047
	const char *fullnode;
42067
b01bbb8ff1f2 cext: make revlog.c PY_SSIZE_T_CLEAN
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41283
diff changeset
  2048
	Py_ssize_t nodelen;
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2049
	char *node;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2050
	int rev, i;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2051
36620
186c6df3a373 py3: bulk-replace 'const char*' format specifier passed to PyArg_ParseTuple*()
Yuya Nishihara <yuya@tcha.org>
parents: 36619
diff changeset
  2052
	if (!PyArg_ParseTuple(args, PY23("s#", "y#"), &node, &nodelen))
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2053
		return NULL;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2054
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
  2055
	if (nodelen < 1) {
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2056
		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
  2057
		return NULL;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2058
	}
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2059
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
  2060
	if (nodelen > 2 * self->nodelen) {
17353
bde1185f406c revlog: don't try to partialmatch strings those length > 40
sorcerer
parents: 17165
diff changeset
  2061
		PyErr_SetString(PyExc_ValueError, "key too long");
bde1185f406c revlog: don't try to partialmatch strings those length > 40
sorcerer
parents: 17165
diff changeset
  2062
		return NULL;
bde1185f406c revlog: don't try to partialmatch strings those length > 40
sorcerer
parents: 17165
diff changeset
  2063
	}
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2064
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2065
	for (i = 0; i < nodelen; i++)
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2066
		hexdigit(node, i);
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2067
	if (PyErr_Occurred()) {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2068
		/* input contains non-hex characters */
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2069
		PyErr_Clear();
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2070
		Py_RETURN_NONE;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2071
	}
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2072
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
  2073
	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
  2074
		return NULL;
38942
3e74c01102af index: rename "nt_*(indexObject *self,...)" functions to "index_*"
Martin von Zweigbergk <martinvonz@google.com>
parents: 38941
diff changeset
  2075
	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
  2076
		return NULL;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  2077
	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
  2078
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2079
	switch (rev) {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2080
	case -4:
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2081
		raise_revlog_error();
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2082
		return NULL;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2083
	case -2:
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2084
		Py_RETURN_NONE;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2085
	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
  2086
		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
  2087
	}
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2088
37860
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
  2089
	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
  2090
	if (fullnode == NULL) {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2091
		return NULL;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2092
	}
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
  2093
	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
  2094
}
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2095
37968
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
  2096
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
  2097
{
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
  2098
	PyObject *val;
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
  2099
	char *node;
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
  2100
	int length;
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
  2101
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
  2102
	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
  2103
		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
  2104
	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
  2105
		return NULL;
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
  2106
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
  2107
	self->ntlookups++;
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
  2108
	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
  2109
		return NULL;
38942
3e74c01102af index: rename "nt_*(indexObject *self,...)" functions to "index_*"
Martin von Zweigbergk <martinvonz@google.com>
parents: 38941
diff changeset
  2110
	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
  2111
		return NULL;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  2112
	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
  2113
	if (length == -3)
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
  2114
		return NULL;
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
  2115
	if (length == -2) {
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
  2116
		raise_revlog_error();
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
  2117
		return NULL;
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
  2118
	}
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
  2119
	return PyInt_FromLong(length);
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
  2120
}
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
  2121
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2122
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
  2123
{
16679
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
  2124
	PyObject *val;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2125
	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
  2126
	int rev;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2127
16679
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
  2128
	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
  2129
		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
  2130
	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
  2131
		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
  2132
	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
  2133
	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
  2134
		return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2135
	if (rev == -2)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2136
		Py_RETURN_NONE;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2137
	return PyInt_FromLong(rev);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2138
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2139
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2140
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
  2141
{
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2142
	char *node;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2143
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2144
	if (PyInt_Check(value)) {
40598
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
  2145
		long rev;
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
  2146
		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
  2147
			return -1;
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
  2148
		}
38866
aa33988ad8ab index: return False for "len(index) in index"
Martin von Zweigbergk <martinvonz@google.com>
parents: 38852
diff changeset
  2149
		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
  2150
	}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2151
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
  2152
	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
  2153
		return -1;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2154
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
  2155
	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
  2156
	case -3:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2157
		return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2158
	case -2:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2159
		return 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2160
	default:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2161
		return 1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2162
	}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2163
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2164
43534
0c659fc20207 index: add a `has_node` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43532
diff changeset
  2165
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
  2166
{
0c659fc20207 index: add a `has_node` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43532
diff changeset
  2167
	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
  2168
	if (ret < 0)
0c659fc20207 index: add a `has_node` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43532
diff changeset
  2169
		return NULL;
0c659fc20207 index: add a `has_node` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43532
diff changeset
  2170
	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
  2171
}
0c659fc20207 index: add a `has_node` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43532
diff changeset
  2172
43552
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
  2173
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
  2174
{
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
  2175
	char *node;
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
  2176
	int rev;
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
  2177
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
  2178
	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
  2179
		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
  2180
	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
  2181
	if (rev >= -1)
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
  2182
		return PyInt_FromLong(rev);
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
  2183
	if (rev == -2)
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
  2184
		raise_revlog_error();
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
  2185
	return NULL;
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
  2186
}
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
  2187
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2188
typedef uint64_t bitmask;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2189
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2190
/*
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2191
 * 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
  2192
 * 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
  2193
 * "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
  2194
 */
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2195
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
  2196
                                     int revcount)
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2197
{
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2198
	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
  2199
	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
  2200
	PyObject *gca = PyList_New(0);
20555
4add43865a9b ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents: 20554
diff changeset
  2201
	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
  2202
	int maxrev = -1;
22399
9f490afcb067 parsers: use bitmask type consistently in find_gca_candidates
Henrik Stuart <hg@hstuart.dk>
parents: 21871
diff changeset
  2203
	bitmask sp;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2204
	bitmask *seen;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2205
19727
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
  2206
	if (gca == NULL)
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
  2207
		return PyErr_NoMemory();
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
  2208
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2209
	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
  2210
		if (revs[i] > maxrev)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2211
			maxrev = revs[i];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2212
	}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2213
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2214
	seen = calloc(sizeof(*seen), maxrev + 1);
19727
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
  2215
	if (seen == NULL) {
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
  2216
		Py_DECREF(gca);
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2217
		return PyErr_NoMemory();
19727
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
  2218
	}
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2219
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2220
	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
  2221
		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
  2222
20555
4add43865a9b ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents: 20554
diff changeset
  2223
	interesting = revcount;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2224
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2225
	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
  2226
		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
  2227
		int parents[2];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2228
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2229
		if (!sv)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2230
			continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2231
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2232
		if (sv < poison) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2233
			interesting -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2234
			if (sv == allseen) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2235
				PyObject *obj = PyInt_FromLong(v);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2236
				if (obj == NULL)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2237
					goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2238
				if (PyList_Append(gca, obj) == -1) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2239
					Py_DECREF(obj);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2240
					goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2241
				}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2242
				sv |= poison;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2243
				for (i = 0; i < revcount; i++) {
20555
4add43865a9b ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents: 20554
diff changeset
  2244
					if (revs[i] == v)
4add43865a9b ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents: 20554
diff changeset
  2245
						goto done;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2246
				}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2247
			}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2248
		}
25810
82d6a35cf432 parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents: 25584
diff changeset
  2249
		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
  2250
			goto bail;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2251
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2252
		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
  2253
			int p = parents[i];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2254
			if (p == -1)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2255
				continue;
19030
48d6f436363e parsers: fix variable declaration position issue
Matt Mackall <mpm@selenic.com>
parents: 18988
diff changeset
  2256
			sp = seen[p];
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2257
			if (sv < poison) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2258
				if (sp == 0) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2259
					seen[p] = sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2260
					interesting++;
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2261
				} 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
  2262
					seen[p] |= sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2263
			} else {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2264
				if (sp && sp < poison)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2265
					interesting--;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2266
				seen[p] = sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2267
			}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2268
		}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2269
	}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2270
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2271
done:
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2272
	free(seen);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2273
	return gca;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2274
bail:
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2275
	free(seen);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2276
	Py_XDECREF(gca);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2277
	return NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2278
}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2279
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2280
/*
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2281
 * 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
  2282
 * path to the root.
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2283
 */
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2284
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
  2285
{
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2286
	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
  2287
	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
  2288
	int *depth, *interesting = NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2289
	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
  2290
	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
  2291
	long *seen = NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2292
	int maxrev = -1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2293
	long final;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2294
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2295
	if (revcount > capacity) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2296
		PyErr_Format(PyExc_OverflowError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2297
		             "bitset size (%ld) > capacity (%ld)",
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2298
		             (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
  2299
		return NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2300
	}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2301
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2302
	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
  2303
		int n = (int)PyInt_AsLong(PyList_GET_ITEM(revs, i));
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2304
		if (n > maxrev)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2305
			maxrev = n;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2306
	}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2307
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2308
	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
  2309
	if (depth == NULL)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2310
		return PyErr_NoMemory();
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2311
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2312
	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
  2313
	if (seen == NULL) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2314
		PyErr_NoMemory();
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2315
		goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2316
	}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2317
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
  2318
	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
  2319
	if (interesting == NULL) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2320
		PyErr_NoMemory();
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2321
		goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2322
	}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2323
19502
8704477ad3b6 ancestor.deepest: sort revs in C version
Siddharth Agarwal <sid0@fb.com>
parents: 19062
diff changeset
  2324
	if (PyList_Sort(revs) == -1)
8704477ad3b6 ancestor.deepest: sort revs in C version
Siddharth Agarwal <sid0@fb.com>
parents: 19062
diff changeset
  2325
		goto bail;
8704477ad3b6 ancestor.deepest: sort revs in C version
Siddharth Agarwal <sid0@fb.com>
parents: 19062
diff changeset
  2326
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2327
	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
  2328
		int n = (int)PyInt_AsLong(PyList_GET_ITEM(revs, i));
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2329
		long b = 1l << i;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2330
		depth[n] = 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2331
		seen[n] = b;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2332
		interesting[b] = 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2333
	}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2334
33475
f501322512b6 parsers: fix invariant bug in find_deepest (issue5623)
Sune Foldager <cryo@cyanite.org>
parents: 33174
diff changeset
  2335
	/* 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
  2336
	 * interesting. */
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2337
	ninteresting = (int)revcount;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2338
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2339
	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
  2340
		int dv = depth[v];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2341
		int parents[2];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2342
		long sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2343
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2344
		if (dv == 0)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2345
			continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2346
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2347
		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
  2348
		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
  2349
			goto bail;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2350
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2351
		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
  2352
			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
  2353
			long sp;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2354
			int dp;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2355
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2356
			if (p == -1)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2357
				continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2358
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2359
			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
  2360
			sp = seen[p];
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2361
			if (dp <= dv) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2362
				depth[p] = dv + 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2363
				if (sp != sv) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2364
					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
  2365
					seen[p] = sv;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2366
					if (sp) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2367
						interesting[sp] -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2368
						if (interesting[sp] == 0)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2369
							ninteresting -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2370
					}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2371
				}
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2372
			} 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
  2373
				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
  2374
				if (nsp == sp)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2375
					continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2376
				seen[p] = nsp;
19503
f2dfda6ac152 ancestor.deepest: decrement ninteresting correctly (issue3984)
Wei, Elson <elson.wei@gmail.com>
parents: 19502
diff changeset
  2377
				interesting[sp] -= 1;
33475
f501322512b6 parsers: fix invariant bug in find_deepest (issue5623)
Sune Foldager <cryo@cyanite.org>
parents: 33174
diff changeset
  2378
				if (interesting[sp] == 0)
19503
f2dfda6ac152 ancestor.deepest: decrement ninteresting correctly (issue3984)
Wei, Elson <elson.wei@gmail.com>
parents: 19502
diff changeset
  2379
					ninteresting -= 1;
33475
f501322512b6 parsers: fix invariant bug in find_deepest (issue5623)
Sune Foldager <cryo@cyanite.org>
parents: 33174
diff changeset
  2380
				if (interesting[nsp] == 0)
f501322512b6 parsers: fix invariant bug in find_deepest (issue5623)
Sune Foldager <cryo@cyanite.org>
parents: 33174
diff changeset
  2381
					ninteresting += 1;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2382
				interesting[nsp] += 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2383
			}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2384
		}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2385
		interesting[sv] -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2386
		if (interesting[sv] == 0)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2387
			ninteresting -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2388
	}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2389
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2390
	final = 0;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2391
	j = ninteresting;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2392
	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
  2393
		if (interesting[i] == 0)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2394
			continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2395
		final |= i;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2396
		j -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2397
	}
21730
8da100383dc3 parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents: 21103
diff changeset
  2398
	if (final == 0) {
8da100383dc3 parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents: 21103
diff changeset
  2399
		keys = PyList_New(0);
8da100383dc3 parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents: 21103
diff changeset
  2400
		goto bail;
8da100383dc3 parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents: 21103
diff changeset
  2401
	}
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2402
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2403
	dict = PyDict_New();
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2404
	if (dict == NULL)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2405
		goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2406
19504
2fa303619b4d ancestor.deepest: ignore ninteresting while building result (issue3984)
Siddharth Agarwal <sid0@fb.com>
parents: 19503
diff changeset
  2407
	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
  2408
		PyObject *key;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2409
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2410
		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
  2411
			continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2412
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2413
		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
  2414
		Py_INCREF(key);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2415
		Py_INCREF(Py_None);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2416
		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
  2417
			Py_DECREF(key);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2418
			Py_DECREF(Py_None);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2419
			goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2420
		}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2421
	}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2422
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2423
	keys = PyDict_Keys(dict);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2424
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2425
bail:
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2426
	free(depth);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2427
	free(seen);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2428
	free(interesting);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2429
	Py_XDECREF(dict);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2430
21730
8da100383dc3 parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents: 21103
diff changeset
  2431
	return keys;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2432
}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2433
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2434
/*
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2435
 * Given a (possibly overlapping) set of revs, return all the
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2436
 * common ancestors heads: heads(::args[0] and ::a[1] and ...)
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2437
 */
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2438
static PyObject *index_commonancestorsheads(indexObject *self, PyObject *args)
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2439
{
21103
628c16489d1c parsers: remove unnecessary gca variable in index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 21102
diff changeset
  2440
	PyObject *ret = NULL;
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2441
	Py_ssize_t argcount, i, len;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2442
	bitmask repeat = 0;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2443
	int revcount = 0;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2444
	int *revs;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2445
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2446
	argcount = PySequence_Length(args);
31469
a43fd9ec2a39 parsers: use Python memory allocator in commonancestorsheads()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31426
diff changeset
  2447
	revs = PyMem_Malloc(argcount * sizeof(*revs));
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2448
	if (argcount > 0 && revs == NULL)
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2449
		return PyErr_NoMemory();
38851
781b2720d2ac index: don't include nullid in len()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38850
diff changeset
  2450
	len = index_length(self);
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2451
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2452
	for (i = 0; i < argcount; i++) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2453
		static const int capacity = 24;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2454
		PyObject *obj = PySequence_GetItem(args, i);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2455
		bitmask x;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2456
		long val;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2457
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2458
		if (!PyInt_Check(obj)) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2459
			PyErr_SetString(PyExc_TypeError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2460
			                "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
  2461
			Py_DECREF(obj);
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2462
			goto bail;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2463
		}
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2464
		val = PyInt_AsLong(obj);
23945
33d6aaf84c9e parsers.c: fix a memory leak in index_commonancestorsheads
Augie Fackler <augie@google.com>
parents: 23944
diff changeset
  2465
		Py_DECREF(obj);
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2466
		if (val == -1) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2467
			ret = PyList_New(0);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2468
			goto done;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2469
		}
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2470
		if (val < 0 || val >= len) {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2471
			PyErr_SetString(PyExc_IndexError, "index out of range");
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2472
			goto bail;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2473
		}
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2474
		/* this cheesy bloom filter lets us avoid some more
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2475
		 * expensive duplicate checks in the common set-is-disjoint
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2476
		 * case */
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2477
		x = 1ull << (val & 0x3f);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2478
		if (repeat & x) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2479
			int k;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2480
			for (k = 0; k < revcount; k++) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2481
				if (val == revs[k])
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2482
					goto duplicate;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2483
			}
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2484
		} else
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2485
			repeat |= x;
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2486
		if (revcount >= capacity) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2487
			PyErr_Format(PyExc_OverflowError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2488
			             "bitset size (%d) > capacity (%d)",
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2489
			             revcount, capacity);
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2490
			goto bail;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2491
		}
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2492
		revs[revcount++] = (int)val;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2493
	duplicate:;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2494
	}
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2495
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2496
	if (revcount == 0) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2497
		ret = PyList_New(0);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2498
		goto done;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2499
	}
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2500
	if (revcount == 1) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2501
		PyObject *obj;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2502
		ret = PyList_New(1);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2503
		if (ret == NULL)
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2504
			goto bail;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2505
		obj = PyInt_FromLong(revs[0]);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2506
		if (obj == NULL)
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2507
			goto bail;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2508
		PyList_SET_ITEM(ret, 0, obj);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2509
		goto done;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2510
	}
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2511
21103
628c16489d1c parsers: remove unnecessary gca variable in index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 21102
diff changeset
  2512
	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
  2513
	if (ret == NULL)
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2514
		goto bail;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2515
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2516
done:
31469
a43fd9ec2a39 parsers: use Python memory allocator in commonancestorsheads()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31426
diff changeset
  2517
	PyMem_Free(revs);
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2518
	return ret;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2519
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2520
bail:
31469
a43fd9ec2a39 parsers: use Python memory allocator in commonancestorsheads()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31426
diff changeset
  2521
	PyMem_Free(revs);
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2522
	Py_XDECREF(ret);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2523
	return NULL;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2524
}
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2525
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2526
/*
24004
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  2527
 * 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
  2528
 * 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
  2529
 */
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  2530
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
  2531
{
26048
0be2f81aadc3 parsers: fix two leaks in index_ancestors
Augie Fackler <augie@google.com>
parents: 26044
diff changeset
  2532
	PyObject *ret;
24004
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  2533
	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
  2534
	if (gca == NULL)
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  2535
		return NULL;
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  2536
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  2537
	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
  2538
		return gca;
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  2539
	}
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  2540
26048
0be2f81aadc3 parsers: fix two leaks in index_ancestors
Augie Fackler <augie@google.com>
parents: 26044
diff changeset
  2541
	ret = find_deepest(self, gca);
0be2f81aadc3 parsers: fix two leaks in index_ancestors
Augie Fackler <augie@google.com>
parents: 26044
diff changeset
  2542
	Py_DECREF(gca);
0be2f81aadc3 parsers: fix two leaks in index_ancestors
Augie Fackler <augie@google.com>
parents: 26044
diff changeset
  2543
	return ret;
24004
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  2544
}
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  2545
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  2546
/*
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2547
 * 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
  2548
 */
38942
3e74c01102af index: rename "nt_*(indexObject *self,...)" functions to "index_*"
Martin von Zweigbergk <martinvonz@google.com>
parents: 38941
diff changeset
  2549
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
  2550
{
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  2551
	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
  2552
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  2553
	len = self->length + self->new_length;
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  2554
	i = start - self->length;
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  2555
	if (i < 0)
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  2556
		return;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2557
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  2558
	for (i = start; i < len; i++)
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  2559
		nt_delete_node(&self->nt, index_deref(self, i) + 32);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  2560
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  2561
	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
  2562
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2563
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2564
/*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2565
 * 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
  2566
 * range.
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2567
 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2568
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
  2569
{
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2570
	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
  2571
	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
  2572
	int ret = 0;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2573
30171
7a3b59f0329a parsers: avoid PySliceObject cast on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30169
diff changeset
  2574
/* Argument changed from PySliceObject* to PyObject* in Python 3. */
7a3b59f0329a parsers: avoid PySliceObject cast on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30169
diff changeset
  2575
#ifdef IS_PY3K
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2576
	if (PySlice_GetIndicesEx(item, length, &start, &stop, &step,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2577
	                         &slicelength) < 0)
30171
7a3b59f0329a parsers: avoid PySliceObject cast on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30169
diff changeset
  2578
#else
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2579
	if (PySlice_GetIndicesEx((PySliceObject *)item, length, &start, &stop,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2580
	                         &step, &slicelength) < 0)
30171
7a3b59f0329a parsers: avoid PySliceObject cast on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30169
diff changeset
  2581
#endif
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2582
		return -1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2583
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2584
	if (slicelength <= 0)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2585
		return 0;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2586
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2587
	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
  2588
		stop = start;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2589
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2590
	if (step < 0) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2591
		stop = start + 1;
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2592
		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
  2593
		step = -step;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2594
	}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2595
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2596
	if (step != 1) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2597
		PyErr_SetString(PyExc_ValueError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2598
		                "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
  2599
		return -1;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2600
	}
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2601
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2602
	if (stop != length - 1) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2603
		PyErr_SetString(PyExc_IndexError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2604
		                "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
  2605
		return -1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2606
	}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2607
39068
52e9bf215f96 index: don't include nullid in the internal "length" field
Martin von Zweigbergk <martinvonz@google.com>
parents: 38944
diff changeset
  2608
	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
  2609
		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
  2610
			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
  2611
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
  2612
			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
  2613
				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
  2614
				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
  2615
					return -1;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2616
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  2617
				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
  2618
			}
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  2619
			if (self->new_length)
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  2620
				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
  2621
			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
  2622
				self->ntrev = (int)start;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  2623
		} else if (self->new_length) {
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  2624
			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
  2625
		}
43847
49fa0b31ee1d cext-revlog: fixed __delitem__ for uninitialized nodetree
Georges Racinet <georges.racinet@octobus.net>
parents: 43582
diff changeset
  2626
39068
52e9bf215f96 index: don't include nullid in the internal "length" field
Martin von Zweigbergk <martinvonz@google.com>
parents: 38944
diff changeset
  2627
		self->length = start;
16784
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
  2628
		goto done;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2629
	}
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2630
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  2631
	if (self->ntinitialized) {
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  2632
		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
  2633
		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
  2634
			self->ntrev = (int)start;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  2635
	} else {
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  2636
		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
  2637
	}
16784
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
  2638
done:
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  2639
	Py_CLEAR(self->headrevs);
16784
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
  2640
	return ret;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2641
}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2642
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2643
/*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2644
 * Supported ops:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2645
 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2646
 * slice deletion
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2647
 * 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
  2648
 * 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
  2649
 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2650
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
  2651
                                  PyObject *value)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2652
{
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2653
	char *node;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2654
	long rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2655
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2656
	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
  2657
		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
  2658
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
  2659
	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
  2660
		return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2661
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2662
	if (value == NULL)
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2663
		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
  2664
		                           : 0;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2665
	rev = PyInt_AsLong(value);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2666
	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
  2667
		if (!PyErr_Occurred())
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2668
			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
  2669
		return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2670
	}
23468
ee311681e591 parsers: ensure revlog index node tree is initialized before insertion
Mike Edgar <adgar@google.com>
parents: 23087
diff changeset
  2671
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
  2672
	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
  2673
		return -1;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  2674
	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
  2675
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2676
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2677
/*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2678
 * 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
  2679
 * 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
  2680
 */
22401
9ba8a93e55f5 parsers: ensure correct return type for inline_scan
Henrik Stuart <hg@hstuart.dk>
parents: 22400
diff changeset
  2681
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
  2682
{
30577
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
  2683
	const char *data = (const char *)self->buf.buf;
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
  2684
	Py_ssize_t pos = 0;
30577
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
  2685
	Py_ssize_t end = self->buf.len;
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2686
	long incr = self->hdrsize;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2687
	Py_ssize_t len = 0;
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
  2688
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2689
	while (pos + self->hdrsize <= end && pos >= 0) {
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2690
		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
  2691
		/* 3rd element of header is length of compressed inline data */
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
  2692
		comp_len = getbe32(data + pos + 8);
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2693
		if (self->hdrsize == v2_hdrsize) {
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2694
			sidedata_comp_len = getbe32(data + pos + 72);
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2695
		}
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2696
		incr = self->hdrsize + 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
  2697
		if (offsets)
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
  2698
			offsets[len] = data + pos;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2699
		len++;
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
  2700
		pos += incr;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2701
	}
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
  2702
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
  2703
	if (pos != end) {
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2704
		if (!PyErr_Occurred())
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2705
			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
  2706
		return -1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2707
	}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2708
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2709
	return len;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2710
}
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
  2711
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2712
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
  2713
{
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2714
	PyObject *data_obj, *inlined_obj, *revlogv2;
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2715
	Py_ssize_t size;
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2716
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2717
	static char *kwlist[] = {"data", "inlined", "revlogv2", NULL};
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2718
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2719
	/* 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
  2720
	 */
20109
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
  2721
	self->added = NULL;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  2722
	self->new_length = 0;
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  2723
	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
  2724
	self->data = NULL;
30577
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
  2725
	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
  2726
	self->headrevs = NULL;
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  2727
	self->filteredrevs = Py_None;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  2728
	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
  2729
	self->ntinitialized = 0;
20109
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
  2730
	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
  2731
	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
  2732
	self->nullentry = NULL;
20109
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
  2733
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2734
	revlogv2 = NULL;
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2735
	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O", kwlist,
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2736
	                                 &data_obj, &inlined_obj, &revlogv2))
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2737
		return -1;
30577
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
  2738
	if (!PyObject_CheckBuffer(data_obj)) {
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
  2739
		PyErr_SetString(PyExc_TypeError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2740
		                "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
  2741
		return -1;
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2742
	}
46144
e4f6dae01b3b cext: shut-up sign compare warnings
Joerg Sonnenberger <joerg@bec.de>
parents: 46141
diff changeset
  2743
	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
  2744
		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
  2745
		return -1;
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
  2746
	}
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
  2747
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2748
	if (revlogv2 && PyObject_IsTrue(revlogv2)) {
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2749
		self->hdrsize = v2_hdrsize;
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2750
	} else {
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2751
		self->hdrsize = v1_hdrsize;
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2752
	}
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2753
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2754
	if (self->hdrsize == v1_hdrsize) {
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2755
		self->nullentry =
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2756
		    Py_BuildValue(PY23("iiiiiiis#", "iiiiiiiy#"), 0, 0, 0, -1,
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2757
		                  -1, -1, -1, nullid, self->nodelen);
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2758
	} else {
46875
651e6df2b0a4 clang-format: run the formatter on mercurial/cext/revlog.c
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
  2759
		self->nullentry =
651e6df2b0a4 clang-format: run the formatter on mercurial/cext/revlog.c
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
  2760
		    Py_BuildValue(PY23("iiiiiiis#ii", "iiiiiiiy#ii"), 0, 0, 0,
651e6df2b0a4 clang-format: run the formatter on mercurial/cext/revlog.c
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
  2761
		                  -1, -1, -1, -1, nullid, self->nodelen, 0, 0);
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2762
	}
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2763
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
  2764
	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
  2765
		return -1;
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
  2766
	PyObject_GC_UnTrack(self->nullentry);
30577
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
  2767
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
  2768
	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
  2769
		return -1;
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
  2770
	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
  2771
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2772
	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
  2773
	self->data = data_obj;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2774
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2775
	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
  2776
	self->ntrev = -1;
16597
b767382a8675 parsers: fix refcount bug on corrupt index
Matt Mackall <mpm@selenic.com>
parents: 16572
diff changeset
  2777
	Py_INCREF(self->data);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2778
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2779
	if (self->inlined) {
22401
9ba8a93e55f5 parsers: ensure correct return type for inline_scan
Henrik Stuart <hg@hstuart.dk>
parents: 22400
diff changeset
  2780
		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
  2781
		if (len == -1)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2782
			goto bail;
39068
52e9bf215f96 index: don't include nullid in the internal "length" field
Martin von Zweigbergk <martinvonz@google.com>
parents: 38944
diff changeset
  2783
		self->length = len;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2784
	} else {
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2785
		if (size % self->hdrsize) {
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2786
			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
  2787
			goto bail;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2788
		}
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2789
		self->length = size / self->hdrsize;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2790
	}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2791
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2792
	return 0;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2793
bail:
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2794
	return -1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2795
}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2796
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2797
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
  2798
{
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2799
	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
  2800
	return (PyObject *)self;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2801
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2802
38944
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
  2803
static void _index_clearcaches(indexObject *self)
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
  2804
{
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
  2805
	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
  2806
		PyMem_Free((void *)self->offsets);
38944
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
  2807
		self->offsets = NULL;
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
  2808
	}
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  2809
	if (self->ntinitialized) {
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  2810
		nt_dealloc(&self->nt);
38944
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
  2811
	}
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
  2812
	self->ntinitialized = 0;
38944
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
  2813
	Py_CLEAR(self->headrevs);
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
  2814
}
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
  2815
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
  2816
static PyObject *index_clearcaches(indexObject *self)
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
  2817
{
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
  2818
	_index_clearcaches(self);
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
  2819
	self->ntrev = -1;
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
  2820
	self->ntlookups = self->ntmisses = 0;
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
  2821
	Py_RETURN_NONE;
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
  2822
}
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
  2823
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2824
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
  2825
{
16370
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
  2826
	_index_clearcaches(self);
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  2827
	Py_XDECREF(self->filteredrevs);
30577
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
  2828
	if (self->buf.buf) {
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
  2829
		PyBuffer_Release(&self->buf);
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
  2830
		memset(&self->buf, 0, sizeof(self->buf));
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
  2831
	}
20109
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
  2832
	Py_XDECREF(self->data);
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
  2833
	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
  2834
	Py_XDECREF(self->nullentry);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2835
	PyObject_Del(self);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2836
}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2837
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2838
static PySequenceMethods index_sequence_methods = {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2839
    (lenfunc)index_length,      /* sq_length */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2840
    0,                          /* sq_concat */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2841
    0,                          /* sq_repeat */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2842
    (ssizeargfunc)index_get,    /* sq_item */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2843
    0,                          /* sq_slice */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2844
    0,                          /* sq_ass_item */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2845
    0,                          /* sq_ass_slice */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2846
    (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
  2847
};
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2848
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2849
static PyMappingMethods index_mapping_methods = {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2850
    (lenfunc)index_length,                 /* mp_length */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2851
    (binaryfunc)index_getitem,             /* mp_subscript */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2852
    (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
  2853
};
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2854
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2855
static PyMethodDef index_methods[] = {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2856
    {"ancestors", (PyCFunction)index_ancestors, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2857
     "return the gca set of the given revs"},
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2858
    {"commonancestorsheads", (PyCFunction)index_commonancestorsheads,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2859
     METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2860
     "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
  2861
    {"clearcaches", (PyCFunction)index_clearcaches, METH_NOARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2862
     "clear the index caches"},
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2863
    {"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
  2864
    {"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
  2865
     "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
  2866
    {"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
  2867
     "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
  2868
    {"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
  2869
     "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
  2870
    {"computephasesmapsets", (PyCFunction)compute_phases_map_sets, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2871
     "compute phases"},
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2872
    {"reachableroots2", (PyCFunction)reachableroots2, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2873
     "reachableroots"},
46717
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
  2874
    {"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
  2875
     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
  2876
    {"headrevs", (PyCFunction)index_headrevs, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2877
     "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
  2878
    {"headrevsfiltered", (PyCFunction)index_headrevs, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2879
     "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
  2880
    {"issnapshot", (PyCFunction)index_issnapshot, METH_O,
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
  2881
     "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
  2882
    {"findsnapshots", (PyCFunction)index_findsnapshots, METH_VARARGS,
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
  2883
     "Gather snapshot data in a cache dict"},
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2884
    {"deltachain", (PyCFunction)index_deltachain, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2885
     "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
  2886
    {"slicechunktodensity", (PyCFunction)index_slicechunktodensity,
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
  2887
     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
  2888
    {"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
  2889
    {"partialmatch", (PyCFunction)index_partialmatch, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2890
     "match a potentially ambiguous node ID"},
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2891
    {"shortest", (PyCFunction)index_shortest, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2892
     "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
  2893
    {"stats", (PyCFunction)index_stats, METH_NOARGS, "stats for the index"},
47034
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
  2894
    {"entry_binary", (PyCFunction)index_entry_binary, METH_VARARGS,
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
  2895
     "return an entry in binary form"},
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2896
    {NULL} /* Sentinel */
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2897
};
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2898
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2899
static PyGetSetDef index_getset[] = {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2900
    {"nodemap", (getter)index_nodemap, NULL, "nodemap", NULL},
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2901
    {NULL} /* Sentinel */
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2902
};
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2903
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
  2904
static PyMemberDef index_members[] = {
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
  2905
    {"entry_size", T_LONG, offsetof(indexObject, hdrsize), 0,
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
  2906
     "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
  2907
    {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
  2908
};
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
  2909
40860
18a8def6e1b5 revlog: rename indexType to HgRevlogIndex_Type as it's a global symbol
Yuya Nishihara <yuya@tcha.org>
parents: 40859
diff changeset
  2910
PyTypeObject HgRevlogIndex_Type = {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2911
    PyVarObject_HEAD_INIT(NULL, 0) /* header */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2912
    "parsers.index",               /* tp_name */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2913
    sizeof(indexObject),           /* tp_basicsize */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2914
    0,                             /* tp_itemsize */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2915
    (destructor)index_dealloc,     /* tp_dealloc */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2916
    0,                             /* tp_print */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2917
    0,                             /* tp_getattr */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2918
    0,                             /* tp_setattr */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2919
    0,                             /* tp_compare */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2920
    0,                             /* tp_repr */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2921
    0,                             /* tp_as_number */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2922
    &index_sequence_methods,       /* tp_as_sequence */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2923
    &index_mapping_methods,        /* tp_as_mapping */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2924
    0,                             /* tp_hash */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2925
    0,                             /* tp_call */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2926
    0,                             /* tp_str */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2927
    0,                             /* tp_getattro */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2928
    0,                             /* tp_setattro */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2929
    0,                             /* tp_as_buffer */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2930
    Py_TPFLAGS_DEFAULT,            /* tp_flags */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2931
    "revlog index",                /* tp_doc */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2932
    0,                             /* tp_traverse */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2933
    0,                             /* tp_clear */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2934
    0,                             /* tp_richcompare */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2935
    0,                             /* tp_weaklistoffset */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2936
    0,                             /* tp_iter */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2937
    0,                             /* tp_iternext */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2938
    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
  2939
    index_members,                 /* tp_members */
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2940
    index_getset,                  /* tp_getset */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2941
    0,                             /* tp_base */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2942
    0,                             /* tp_dict */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2943
    0,                             /* tp_descr_get */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2944
    0,                             /* tp_descr_set */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2945
    0,                             /* tp_dictoffset */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2946
    (initproc)index_init,          /* tp_init */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
  2947
    0,                             /* tp_alloc */
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2948
};
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2949
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2950
/*
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2951
 * 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
  2952
 * follows:
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2953
 *
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2954
 * 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
  2955
 * 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
  2956
 *        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
  2957
 *
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2958
 * added complications are for backwards compatibility
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2959
 */
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2960
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
  2961
{
45173
2bc5d1531235 revlog: fix excessive decref on tuple creation failure in parse_index2()
Yuya Nishihara <yuya@tcha.org>
parents: 45141
diff changeset
  2962
	PyObject *cache = NULL;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2963
	indexObject *idx;
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2964
	int ret;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2965
40860
18a8def6e1b5 revlog: rename indexType to HgRevlogIndex_Type as it's a global symbol
Yuya Nishihara <yuya@tcha.org>
parents: 40859
diff changeset
  2966
	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
  2967
	if (idx == NULL)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2968
		goto bail;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2969
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
  2970
	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
  2971
	if (ret == -1)
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2972
		goto bail;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2973
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2974
	if (idx->inlined) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2975
		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
  2976
		if (cache == NULL)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2977
			goto bail;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2978
	} else {
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2979
		cache = Py_None;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2980
		Py_INCREF(cache);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2981
	}
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2982
45173
2bc5d1531235 revlog: fix excessive decref on tuple creation failure in parse_index2()
Yuya Nishihara <yuya@tcha.org>
parents: 45141
diff changeset
  2983
	return Py_BuildValue("NN", idx, cache);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2984
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2985
bail:
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2986
	Py_XDECREF(idx);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2987
	Py_XDECREF(cache);
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2988
	return NULL;
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2989
}
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2990
43959
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43847
diff changeset
  2991
static Revlog_CAPI CAPI = {
44066
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 43959
diff changeset
  2992
    /* 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
  2993
       struct or in the ABI of the listed functions */
44502
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44486
diff changeset
  2994
    2,
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44486
diff changeset
  2995
    index_length,
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44486
diff changeset
  2996
    index_node,
43959
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43847
diff changeset
  2997
    HgRevlogIndex_GetParents,
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43847
diff changeset
  2998
};
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43847
diff changeset
  2999
32378
7d0c69505a66 cext: extract revlog/index parsing code to own C file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32372
diff changeset
  3000
void revlog_module_init(PyObject *mod)
24017
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  3001
{
41052
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents: 40963
diff changeset
  3002
	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
  3003
	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
  3004
	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
  3005
		return;
40860
18a8def6e1b5 revlog: rename indexType to HgRevlogIndex_Type as it's a global symbol
Yuya Nishihara <yuya@tcha.org>
parents: 40859
diff changeset
  3006
	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
  3007
	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
  3008
39218
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
  3009
	nodetreeType.tp_new = PyType_GenericNew;
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
  3010
	if (PyType_Ready(&nodetreeType) < 0)
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
  3011
		return;
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
  3012
	Py_INCREF(&nodetreeType);
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
  3013
	PyModule_AddObject(mod, "nodetree", (PyObject *)&nodetreeType);
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
  3014
43959
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43847
diff changeset
  3015
	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
  3016
	if (caps != NULL)
43959
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43847
diff changeset
  3017
		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
  3018
}