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