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