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