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