mercurial/parsers.c
author Siddharth Agarwal <sid0@fb.com>
Mon, 15 Jun 2015 22:37:33 -0700
changeset 25583 ce64c9ab19f2
parent 25582 5fa399a0c385
child 25584 72b2711f12ea
permissions -rw-r--r--
parsers: factor out code to create a presized dict In upcoming patches we'll expose this as an API.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     1
/*
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     2
 parsers.c - efficient content parsing
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     3
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     4
 Copyright 2008 Matt Mackall <mpm@selenic.com> and others
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     5
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     6
 This software may be used and distributed according to the terms of
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     7
 the GNU General Public License, incorporated herein by reference.
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     8
*/
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     9
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    10
#include <Python.h>
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    11
#include <ctype.h>
17356
511dfb34b412 parsers: fix an integer size warning issued by clang
Bryan O'Sullivan <bryano@fb.com>
parents: 17353
diff changeset
    12
#include <stddef.h>
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    13
#include <string.h>
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    14
11361
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
    15
#include "util.h"
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
    16
20742
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
    17
static char *versionerrortext = "Python minor version mismatch";
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
    18
19718
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    19
static int8_t hextable[256] = {
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    20
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    21
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    22
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    23
	 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1, /* 0-9 */
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    24
	-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* A-F */
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    25
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    26
	-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* a-f */
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    27
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    28
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    29
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    30
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    31
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    32
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    33
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    34
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    35
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    36
};
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    37
22778
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
    38
static char lowertable[128] = {
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
    39
	'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
    40
	'\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
    41
	'\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
    42
	'\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f',
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
    43
	'\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27',
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
    44
	'\x28', '\x29', '\x2a', '\x2b', '\x2c', '\x2d', '\x2e', '\x2f',
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
    45
	'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37',
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
    46
	'\x38', '\x39', '\x3a', '\x3b', '\x3c', '\x3d', '\x3e', '\x3f',
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
    47
	'\x40',
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
    48
	        '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', /* A-G */
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
    49
	'\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f', /* H-O */
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
    50
	'\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77', /* P-W */
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
    51
	'\x78', '\x79', '\x7a',                                         /* X-Z */
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
    52
	                        '\x5b', '\x5c', '\x5d', '\x5e', '\x5f',
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
    53
	'\x60', '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67',
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
    54
	'\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f',
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
    55
	'\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77',
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
    56
	'\x78', '\x79', '\x7a', '\x7b', '\x7c', '\x7d', '\x7e', '\x7f'
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
    57
};
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
    58
24577
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
    59
static char uppertable[128] = {
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
    60
	'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
    61
	'\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
    62
	'\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
    63
	'\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f',
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
    64
	'\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27',
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
    65
	'\x28', '\x29', '\x2a', '\x2b', '\x2c', '\x2d', '\x2e', '\x2f',
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
    66
	'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37',
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
    67
	'\x38', '\x39', '\x3a', '\x3b', '\x3c', '\x3d', '\x3e', '\x3f',
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
    68
	'\x40', '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47',
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
    69
	'\x48', '\x49', '\x4a', '\x4b', '\x4c', '\x4d', '\x4e', '\x4f',
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
    70
	'\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57',
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
    71
	'\x58', '\x59', '\x5a', '\x5b', '\x5c', '\x5d', '\x5e', '\x5f',
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
    72
	'\x60',
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
    73
		'\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47', /* a-g */
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
    74
	'\x48', '\x49', '\x4a', '\x4b', '\x4c', '\x4d', '\x4e', '\x4f', /* h-o */
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
    75
	'\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57', /* p-w */
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
    76
	'\x58', '\x59', '\x5a', 					/* x-z */
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
    77
				'\x7b', '\x7c', '\x7d', '\x7e', '\x7f'
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
    78
};
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
    79
16617
4fb16743049d parsers: change the type signature of hexdigit
Bryan O'Sullivan <bryano@fb.com>
parents: 16616
diff changeset
    80
static inline int hexdigit(const char *p, Py_ssize_t off)
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    81
{
19718
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    82
	int8_t val = hextable[(unsigned char)p[off]];
16617
4fb16743049d parsers: change the type signature of hexdigit
Bryan O'Sullivan <bryano@fb.com>
parents: 16616
diff changeset
    83
19718
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    84
	if (val >= 0) {
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    85
		return val;
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
    86
	}
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    87
7092
fb3fc27617a2 parsers: speed up hex decoding for manifests
Matt Mackall <mpm@selenic.com>
parents: 7091
diff changeset
    88
	PyErr_SetString(PyExc_ValueError, "input contains non-hex character");
fb3fc27617a2 parsers: speed up hex decoding for manifests
Matt Mackall <mpm@selenic.com>
parents: 7091
diff changeset
    89
	return 0;
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    90
}
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    91
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    92
/*
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    93
 * Turn a hex-encoded string into binary.
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    94
 */
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents: 24032
diff changeset
    95
PyObject *unhexlify(const char *str, int len)
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    96
{
7092
fb3fc27617a2 parsers: speed up hex decoding for manifests
Matt Mackall <mpm@selenic.com>
parents: 7091
diff changeset
    97
	PyObject *ret;
6395
3f0294536b24 fix const annotation warning
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6389
diff changeset
    98
	char *d;
16617
4fb16743049d parsers: change the type signature of hexdigit
Bryan O'Sullivan <bryano@fb.com>
parents: 16616
diff changeset
    99
	int i;
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   100
11361
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
   101
	ret = PyBytes_FromStringAndSize(NULL, len / 2);
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
   102
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   103
	if (!ret)
7092
fb3fc27617a2 parsers: speed up hex decoding for manifests
Matt Mackall <mpm@selenic.com>
parents: 7091
diff changeset
   104
		return NULL;
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   105
11361
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
   106
	d = PyBytes_AsString(ret);
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
   107
16617
4fb16743049d parsers: change the type signature of hexdigit
Bryan O'Sullivan <bryano@fb.com>
parents: 16616
diff changeset
   108
	for (i = 0; i < len;) {
4fb16743049d parsers: change the type signature of hexdigit
Bryan O'Sullivan <bryano@fb.com>
parents: 16616
diff changeset
   109
		int hi = hexdigit(str, i++);
4fb16743049d parsers: change the type signature of hexdigit
Bryan O'Sullivan <bryano@fb.com>
parents: 16616
diff changeset
   110
		int lo = hexdigit(str, i++);
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   111
		*d++ = (hi << 4) | lo;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   112
	}
7091
12b35ae03365 parsers: clean up whitespace
Matt Mackall <mpm@selenic.com>
parents: 6395
diff changeset
   113
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   114
	return ret;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   115
}
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   116
24576
fe173106e7fe parsers: make _asciilower a generic _asciitransform function
Siddharth Agarwal <sid0@fb.com>
parents: 24575
diff changeset
   117
static inline PyObject *_asciitransform(PyObject *str_obj,
24606
e4a733c34bc6 parsers._asciitransform: also accept a fallback function
Siddharth Agarwal <sid0@fb.com>
parents: 24577
diff changeset
   118
					const char table[128],
e4a733c34bc6 parsers._asciitransform: also accept a fallback function
Siddharth Agarwal <sid0@fb.com>
parents: 24577
diff changeset
   119
					PyObject *fallback_fn)
22778
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
   120
{
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
   121
	char *str, *newstr;
24574
e97a00bf18ae parsers: factor out most of asciilower into an internal function
Siddharth Agarwal <sid0@fb.com>
parents: 24499
diff changeset
   122
	Py_ssize_t i, len;
22778
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
   123
	PyObject *newobj = NULL;
24575
a62e957413f7 parsers._asciilower: use an explicit return object
Siddharth Agarwal <sid0@fb.com>
parents: 24574
diff changeset
   124
	PyObject *ret = NULL;
22778
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
   125
24574
e97a00bf18ae parsers: factor out most of asciilower into an internal function
Siddharth Agarwal <sid0@fb.com>
parents: 24499
diff changeset
   126
	str = PyBytes_AS_STRING(str_obj);
e97a00bf18ae parsers: factor out most of asciilower into an internal function
Siddharth Agarwal <sid0@fb.com>
parents: 24499
diff changeset
   127
	len = PyBytes_GET_SIZE(str_obj);
22778
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
   128
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
   129
	newobj = PyBytes_FromStringAndSize(NULL, len);
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
   130
	if (!newobj)
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
   131
		goto quit;
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
   132
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
   133
	newstr = PyBytes_AS_STRING(newobj);
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
   134
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
   135
	for (i = 0; i < len; i++) {
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
   136
		char c = str[i];
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
   137
		if (c & 0x80) {
24606
e4a733c34bc6 parsers._asciitransform: also accept a fallback function
Siddharth Agarwal <sid0@fb.com>
parents: 24577
diff changeset
   138
			if (fallback_fn != NULL) {
e4a733c34bc6 parsers._asciitransform: also accept a fallback function
Siddharth Agarwal <sid0@fb.com>
parents: 24577
diff changeset
   139
				ret = PyObject_CallFunctionObjArgs(fallback_fn,
e4a733c34bc6 parsers._asciitransform: also accept a fallback function
Siddharth Agarwal <sid0@fb.com>
parents: 24577
diff changeset
   140
					str_obj, NULL);
e4a733c34bc6 parsers._asciitransform: also accept a fallback function
Siddharth Agarwal <sid0@fb.com>
parents: 24577
diff changeset
   141
			} else {
e4a733c34bc6 parsers._asciitransform: also accept a fallback function
Siddharth Agarwal <sid0@fb.com>
parents: 24577
diff changeset
   142
				PyObject *err = PyUnicodeDecodeError_Create(
e4a733c34bc6 parsers._asciitransform: also accept a fallback function
Siddharth Agarwal <sid0@fb.com>
parents: 24577
diff changeset
   143
					"ascii", str, len, i, (i + 1),
e4a733c34bc6 parsers._asciitransform: also accept a fallback function
Siddharth Agarwal <sid0@fb.com>
parents: 24577
diff changeset
   144
					"unexpected code byte");
e4a733c34bc6 parsers._asciitransform: also accept a fallback function
Siddharth Agarwal <sid0@fb.com>
parents: 24577
diff changeset
   145
				PyErr_SetObject(PyExc_UnicodeDecodeError, err);
e4a733c34bc6 parsers._asciitransform: also accept a fallback function
Siddharth Agarwal <sid0@fb.com>
parents: 24577
diff changeset
   146
				Py_XDECREF(err);
e4a733c34bc6 parsers._asciitransform: also accept a fallback function
Siddharth Agarwal <sid0@fb.com>
parents: 24577
diff changeset
   147
			}
22778
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
   148
			goto quit;
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
   149
		}
24576
fe173106e7fe parsers: make _asciilower a generic _asciitransform function
Siddharth Agarwal <sid0@fb.com>
parents: 24575
diff changeset
   150
		newstr[i] = table[(unsigned char)c];
22778
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
   151
	}
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
   152
24575
a62e957413f7 parsers._asciilower: use an explicit return object
Siddharth Agarwal <sid0@fb.com>
parents: 24574
diff changeset
   153
	ret = newobj;
a62e957413f7 parsers._asciilower: use an explicit return object
Siddharth Agarwal <sid0@fb.com>
parents: 24574
diff changeset
   154
	Py_INCREF(ret);
22778
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
   155
quit:
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
   156
	Py_XDECREF(newobj);
24575
a62e957413f7 parsers._asciilower: use an explicit return object
Siddharth Agarwal <sid0@fb.com>
parents: 24574
diff changeset
   157
	return ret;
22778
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
   158
}
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
   159
24574
e97a00bf18ae parsers: factor out most of asciilower into an internal function
Siddharth Agarwal <sid0@fb.com>
parents: 24499
diff changeset
   160
static PyObject *asciilower(PyObject *self, PyObject *args)
e97a00bf18ae parsers: factor out most of asciilower into an internal function
Siddharth Agarwal <sid0@fb.com>
parents: 24499
diff changeset
   161
{
e97a00bf18ae parsers: factor out most of asciilower into an internal function
Siddharth Agarwal <sid0@fb.com>
parents: 24499
diff changeset
   162
	PyObject *str_obj;
e97a00bf18ae parsers: factor out most of asciilower into an internal function
Siddharth Agarwal <sid0@fb.com>
parents: 24499
diff changeset
   163
	if (!PyArg_ParseTuple(args, "O!:asciilower", &PyBytes_Type, &str_obj))
e97a00bf18ae parsers: factor out most of asciilower into an internal function
Siddharth Agarwal <sid0@fb.com>
parents: 24499
diff changeset
   164
		return NULL;
24606
e4a733c34bc6 parsers._asciitransform: also accept a fallback function
Siddharth Agarwal <sid0@fb.com>
parents: 24577
diff changeset
   165
	return _asciitransform(str_obj, lowertable, NULL);
24574
e97a00bf18ae parsers: factor out most of asciilower into an internal function
Siddharth Agarwal <sid0@fb.com>
parents: 24499
diff changeset
   166
}
e97a00bf18ae parsers: factor out most of asciilower into an internal function
Siddharth Agarwal <sid0@fb.com>
parents: 24499
diff changeset
   167
24577
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
   168
static PyObject *asciiupper(PyObject *self, PyObject *args)
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
   169
{
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
   170
	PyObject *str_obj;
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
   171
	if (!PyArg_ParseTuple(args, "O!:asciiupper", &PyBytes_Type, &str_obj))
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
   172
		return NULL;
24606
e4a733c34bc6 parsers._asciitransform: also accept a fallback function
Siddharth Agarwal <sid0@fb.com>
parents: 24577
diff changeset
   173
	return _asciitransform(str_obj, uppertable, NULL);
24577
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
   174
}
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
   175
25583
ce64c9ab19f2 parsers: factor out code to create a presized dict
Siddharth Agarwal <sid0@fb.com>
parents: 25582
diff changeset
   176
static inline PyObject *_dict_new_presized(Py_ssize_t expected_size)
ce64c9ab19f2 parsers: factor out code to create a presized dict
Siddharth Agarwal <sid0@fb.com>
parents: 25582
diff changeset
   177
{
ce64c9ab19f2 parsers: factor out code to create a presized dict
Siddharth Agarwal <sid0@fb.com>
parents: 25582
diff changeset
   178
	/* _PyDict_NewPresized expects a minused parameter, but it actually
ce64c9ab19f2 parsers: factor out code to create a presized dict
Siddharth Agarwal <sid0@fb.com>
parents: 25582
diff changeset
   179
	   creates a dictionary that's the nearest power of two bigger than the
ce64c9ab19f2 parsers: factor out code to create a presized dict
Siddharth Agarwal <sid0@fb.com>
parents: 25582
diff changeset
   180
	   parameter. For example, with the initial minused = 1000, the
ce64c9ab19f2 parsers: factor out code to create a presized dict
Siddharth Agarwal <sid0@fb.com>
parents: 25582
diff changeset
   181
	   dictionary created has size 1024. Of course in a lot of cases that
ce64c9ab19f2 parsers: factor out code to create a presized dict
Siddharth Agarwal <sid0@fb.com>
parents: 25582
diff changeset
   182
	   can be greater than the maximum load factor Python's dict object
ce64c9ab19f2 parsers: factor out code to create a presized dict
Siddharth Agarwal <sid0@fb.com>
parents: 25582
diff changeset
   183
	   expects (= 2/3), so as soon as we cross the threshold we'll resize
ce64c9ab19f2 parsers: factor out code to create a presized dict
Siddharth Agarwal <sid0@fb.com>
parents: 25582
diff changeset
   184
	   anyway. So create a dictionary that's at least 3/2 the size. */
ce64c9ab19f2 parsers: factor out code to create a presized dict
Siddharth Agarwal <sid0@fb.com>
parents: 25582
diff changeset
   185
	return _PyDict_NewPresized(((1 + expected_size) / 2) * 3);
ce64c9ab19f2 parsers: factor out code to create a presized dict
Siddharth Agarwal <sid0@fb.com>
parents: 25582
diff changeset
   186
}
ce64c9ab19f2 parsers: factor out code to create a presized dict
Siddharth Agarwal <sid0@fb.com>
parents: 25582
diff changeset
   187
24609
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   188
static PyObject *make_file_foldmap(PyObject *self, PyObject *args)
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   189
{
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   190
	PyObject *dmap, *spec_obj, *normcase_fallback;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   191
	PyObject *file_foldmap = NULL;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   192
	enum normcase_spec spec;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   193
	PyObject *k, *v;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   194
	dirstateTupleObject *tuple;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   195
	Py_ssize_t pos = 0;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   196
	const char *table;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   197
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   198
	if (!PyArg_ParseTuple(args, "O!O!O!:make_file_foldmap",
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   199
			      &PyDict_Type, &dmap,
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   200
			      &PyInt_Type, &spec_obj,
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   201
			      &PyFunction_Type, &normcase_fallback))
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   202
		goto quit;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   203
24622
1e05f11619bb parsers.c: avoid implicit conversion loses integer precision warning
André Sintzoff <andre.sintzoff@gmail.com>
parents: 24609
diff changeset
   204
	spec = (int)PyInt_AS_LONG(spec_obj);
24609
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   205
	switch (spec) {
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   206
	case NORMCASE_LOWER:
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   207
		table = lowertable;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   208
		break;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   209
	case NORMCASE_UPPER:
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   210
		table = uppertable;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   211
		break;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   212
	case NORMCASE_OTHER:
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   213
		table = NULL;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   214
		break;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   215
	default:
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   216
		PyErr_SetString(PyExc_TypeError, "invalid normcasespec");
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   217
		goto quit;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   218
	}
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   219
25583
ce64c9ab19f2 parsers: factor out code to create a presized dict
Siddharth Agarwal <sid0@fb.com>
parents: 25582
diff changeset
   220
	/* Add some more entries to deal with additions outside this
ce64c9ab19f2 parsers: factor out code to create a presized dict
Siddharth Agarwal <sid0@fb.com>
parents: 25582
diff changeset
   221
	   function. */
ce64c9ab19f2 parsers: factor out code to create a presized dict
Siddharth Agarwal <sid0@fb.com>
parents: 25582
diff changeset
   222
	file_foldmap = _dict_new_presized((PyDict_Size(dmap) / 10) * 11);
24609
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   223
	if (file_foldmap == NULL)
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   224
		goto quit;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   225
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   226
	while (PyDict_Next(dmap, &pos, &k, &v)) {
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   227
		if (!dirstate_tuple_check(v)) {
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   228
			PyErr_SetString(PyExc_TypeError,
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   229
					"expected a dirstate tuple");
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   230
			goto quit;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   231
		}
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   232
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   233
		tuple = (dirstateTupleObject *)v;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   234
		if (tuple->state != 'r') {
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   235
			PyObject *normed;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   236
			if (table != NULL) {
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   237
				normed = _asciitransform(k, table,
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   238
					normcase_fallback);
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   239
			} else {
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   240
				normed = PyObject_CallFunctionObjArgs(
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   241
					normcase_fallback, k, NULL);
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   242
			}
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   243
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   244
			if (normed == NULL)
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   245
				goto quit;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   246
			if (PyDict_SetItem(file_foldmap, normed, k) == -1)
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   247
				goto quit;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   248
		}
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   249
	}
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   250
	return file_foldmap;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   251
quit:
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   252
	Py_XDECREF(file_foldmap);
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   253
	return NULL;
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   254
}
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
   255
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   256
/*
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   257
 * This code assumes that a manifest is stitched together with newline
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   258
 * ('\n') characters.
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   259
 */
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   260
static PyObject *parse_manifest(PyObject *self, PyObject *args)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   261
{
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   262
	PyObject *mfdict, *fdict;
19728
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
   263
	char *str, *start, *end;
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   264
	int len;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   265
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   266
	if (!PyArg_ParseTuple(args, "O!O!s#:parse_manifest",
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   267
			      &PyDict_Type, &mfdict,
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   268
			      &PyDict_Type, &fdict,
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   269
			      &str, &len))
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   270
		goto quit;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   271
19728
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
   272
	start = str;
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
   273
	end = str + len;
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
   274
	while (start < end) {
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   275
		PyObject *file = NULL, *node = NULL;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   276
		PyObject *flags = NULL;
19728
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
   277
		char *zero = NULL, *newline = NULL;
17356
511dfb34b412 parsers: fix an integer size warning issued by clang
Bryan O'Sullivan <bryano@fb.com>
parents: 17353
diff changeset
   278
		ptrdiff_t nlen;
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   279
19728
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
   280
		zero = memchr(start, '\0', end - start);
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   281
		if (!zero) {
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   282
			PyErr_SetString(PyExc_ValueError,
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   283
					"manifest entry has no separator");
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   284
			goto quit;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   285
		}
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   286
19728
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
   287
		newline = memchr(zero + 1, '\n', end - (zero + 1));
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
   288
		if (!newline) {
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
   289
			PyErr_SetString(PyExc_ValueError,
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
   290
					"manifest contains trailing garbage");
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
   291
			goto quit;
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
   292
		}
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
   293
11361
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
   294
		file = PyBytes_FromStringAndSize(start, zero - start);
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
   295
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   296
		if (!file)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   297
			goto bail;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   298
19728
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
   299
		nlen = newline - zero - 1;
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   300
17356
511dfb34b412 parsers: fix an integer size warning issued by clang
Bryan O'Sullivan <bryano@fb.com>
parents: 17353
diff changeset
   301
		node = unhexlify(zero + 1, nlen > 40 ? 40 : (int)nlen);
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   302
		if (!node)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   303
			goto bail;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   304
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   305
		if (nlen > 40) {
11361
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
   306
			flags = PyBytes_FromStringAndSize(zero + 41,
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   307
							   nlen - 40);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   308
			if (!flags)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   309
				goto bail;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   310
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   311
			if (PyDict_SetItem(fdict, file, flags) == -1)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   312
				goto bail;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   313
		}
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   314
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   315
		if (PyDict_SetItem(mfdict, file, node) == -1)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   316
			goto bail;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   317
19728
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
   318
		start = newline + 1;
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   319
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   320
		Py_XDECREF(flags);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   321
		Py_XDECREF(node);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   322
		Py_XDECREF(file);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   323
		continue;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   324
	bail:
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   325
		Py_XDECREF(flags);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   326
		Py_XDECREF(node);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   327
		Py_XDECREF(file);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   328
		goto quit;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   329
	}
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   330
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   331
	Py_INCREF(Py_None);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   332
	return Py_None;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   333
quit:
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   334
	return NULL;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   335
}
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   336
21809
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   337
static inline dirstateTupleObject *make_dirstate_tuple(char state, int mode,
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   338
						       int size, int mtime)
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   339
{
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   340
	dirstateTupleObject *t = PyObject_New(dirstateTupleObject,
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   341
					      &dirstateTupleType);
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   342
	if (!t)
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   343
		return NULL;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   344
	t->state = state;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   345
	t->mode = mode;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   346
	t->size = size;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   347
	t->mtime = mtime;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   348
	return t;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   349
}
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   350
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   351
static PyObject *dirstate_tuple_new(PyTypeObject *subtype, PyObject *args,
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   352
				    PyObject *kwds)
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   353
{
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   354
	/* We do all the initialization here and not a tp_init function because
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   355
	 * dirstate_tuple is immutable. */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   356
	dirstateTupleObject *t;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   357
	char state;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   358
	int size, mode, mtime;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   359
	if (!PyArg_ParseTuple(args, "ciii", &state, &mode, &size, &mtime))
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   360
		return NULL;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   361
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   362
	t = (dirstateTupleObject *)subtype->tp_alloc(subtype, 1);
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   363
	if (!t)
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   364
		return NULL;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   365
	t->state = state;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   366
	t->mode = mode;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   367
	t->size = size;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   368
	t->mtime = mtime;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   369
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   370
	return (PyObject *)t;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   371
}
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   372
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   373
static void dirstate_tuple_dealloc(PyObject *o)
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   374
{
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   375
	PyObject_Del(o);
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   376
}
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   377
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   378
static Py_ssize_t dirstate_tuple_length(PyObject *o)
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   379
{
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   380
	return 4;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   381
}
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   382
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   383
static PyObject *dirstate_tuple_item(PyObject *o, Py_ssize_t i)
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   384
{
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   385
	dirstateTupleObject *t = (dirstateTupleObject *)o;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   386
	switch (i) {
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   387
	case 0:
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   388
		return PyBytes_FromStringAndSize(&t->state, 1);
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   389
	case 1:
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   390
		return PyInt_FromLong(t->mode);
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   391
	case 2:
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   392
		return PyInt_FromLong(t->size);
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   393
	case 3:
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   394
		return PyInt_FromLong(t->mtime);
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   395
	default:
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   396
		PyErr_SetString(PyExc_IndexError, "index out of range");
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   397
		return NULL;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   398
	}
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   399
}
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   400
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   401
static PySequenceMethods dirstate_tuple_sq = {
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   402
	dirstate_tuple_length,     /* sq_length */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   403
	0,                         /* sq_concat */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   404
	0,                         /* sq_repeat */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   405
	dirstate_tuple_item,       /* sq_item */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   406
	0,                         /* sq_ass_item */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   407
	0,                         /* sq_contains */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   408
	0,                         /* sq_inplace_concat */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   409
	0                          /* sq_inplace_repeat */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   410
};
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   411
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   412
PyTypeObject dirstateTupleType = {
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   413
	PyVarObject_HEAD_INIT(NULL, 0)
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   414
	"dirstate_tuple",          /* tp_name */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   415
	sizeof(dirstateTupleObject),/* tp_basicsize */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   416
	0,                         /* tp_itemsize */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   417
	(destructor)dirstate_tuple_dealloc, /* tp_dealloc */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   418
	0,                         /* tp_print */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   419
	0,                         /* tp_getattr */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   420
	0,                         /* tp_setattr */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   421
	0,                         /* tp_compare */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   422
	0,                         /* tp_repr */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   423
	0,                         /* tp_as_number */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   424
	&dirstate_tuple_sq,        /* tp_as_sequence */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   425
	0,                         /* tp_as_mapping */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   426
	0,                         /* tp_hash  */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   427
	0,                         /* tp_call */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   428
	0,                         /* tp_str */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   429
	0,                         /* tp_getattro */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   430
	0,                         /* tp_setattro */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   431
	0,                         /* tp_as_buffer */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   432
	Py_TPFLAGS_DEFAULT,        /* tp_flags */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   433
	"dirstate tuple",          /* tp_doc */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   434
	0,                         /* tp_traverse */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   435
	0,                         /* tp_clear */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   436
	0,                         /* tp_richcompare */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   437
	0,                         /* tp_weaklistoffset */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   438
	0,                         /* tp_iter */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   439
	0,                         /* tp_iternext */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   440
	0,                         /* tp_methods */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   441
	0,                         /* tp_members */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   442
	0,                         /* tp_getset */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   443
	0,                         /* tp_base */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   444
	0,                         /* tp_dict */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   445
	0,                         /* tp_descr_get */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   446
	0,                         /* tp_descr_set */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   447
	0,                         /* tp_dictoffset */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   448
	0,                         /* tp_init */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   449
	0,                         /* tp_alloc */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   450
	dirstate_tuple_new,        /* tp_new */
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   451
};
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   452
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   453
static PyObject *parse_dirstate(PyObject *self, PyObject *args)
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   454
{
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   455
	PyObject *dmap, *cmap, *parents = NULL, *ret = NULL;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   456
	PyObject *fname = NULL, *cname = NULL, *entry = NULL;
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
   457
	char state, *cur, *str, *cpos;
19725
5e25d71a58cc parsers: state is a char, not an int
Bryan O'Sullivan <bryano@fb.com>
parents: 19718
diff changeset
   458
	int mode, size, mtime;
22403
41e9d58ec56f parsers: avoid signed/unsigned comparison mismatch
Henrik Stuart <hg@hstuart.dk>
parents: 22402
diff changeset
   459
	unsigned int flen, len, pos = 40;
41e9d58ec56f parsers: avoid signed/unsigned comparison mismatch
Henrik Stuart <hg@hstuart.dk>
parents: 22402
diff changeset
   460
	int readlen;
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   461
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   462
	if (!PyArg_ParseTuple(args, "O!O!s#:parse_dirstate",
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   463
			      &PyDict_Type, &dmap,
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   464
			      &PyDict_Type, &cmap,
22403
41e9d58ec56f parsers: avoid signed/unsigned comparison mismatch
Henrik Stuart <hg@hstuart.dk>
parents: 22402
diff changeset
   465
			      &str, &readlen))
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   466
		goto quit;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   467
22403
41e9d58ec56f parsers: avoid signed/unsigned comparison mismatch
Henrik Stuart <hg@hstuart.dk>
parents: 22402
diff changeset
   468
	if (readlen < 0)
41e9d58ec56f parsers: avoid signed/unsigned comparison mismatch
Henrik Stuart <hg@hstuart.dk>
parents: 22402
diff changeset
   469
		goto quit;
41e9d58ec56f parsers: avoid signed/unsigned comparison mismatch
Henrik Stuart <hg@hstuart.dk>
parents: 22402
diff changeset
   470
41e9d58ec56f parsers: avoid signed/unsigned comparison mismatch
Henrik Stuart <hg@hstuart.dk>
parents: 22402
diff changeset
   471
	len = readlen;
41e9d58ec56f parsers: avoid signed/unsigned comparison mismatch
Henrik Stuart <hg@hstuart.dk>
parents: 22402
diff changeset
   472
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   473
	/* read parents */
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   474
	if (len < 40)
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   475
		goto quit;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   476
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   477
	parents = Py_BuildValue("s#s#", str, 20, str + 20, 20);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   478
	if (!parents)
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   479
		goto quit;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   480
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   481
	/* read filenames */
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
   482
	while (pos >= 40 && pos < len) {
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
   483
		cur = str + pos;
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   484
		/* unpack header */
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   485
		state = *cur;
16437
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
   486
		mode = getbe32(cur + 1);
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
   487
		size = getbe32(cur + 5);
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
   488
		mtime = getbe32(cur + 9);
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
   489
		flen = getbe32(cur + 13);
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
   490
		pos += 17;
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   491
		cur += 17;
20316
40f08c31844c parsers: fix 'unsigned expression is always true' warning (issue4142)
David Soria Parra <davidsp@fb.com>
parents: 20169
diff changeset
   492
		if (flen > len - pos) {
7174
4da87407b845 parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7168
diff changeset
   493
			PyErr_SetString(PyExc_ValueError, "overflow in dirstate");
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   494
			goto quit;
7174
4da87407b845 parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7168
diff changeset
   495
		}
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   496
21809
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   497
		entry = (PyObject *)make_dirstate_tuple(state, mode, size,
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   498
							mtime);
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   499
		cpos = memchr(cur, 0, flen);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   500
		if (cpos) {
11361
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
   501
			fname = PyBytes_FromStringAndSize(cur, cpos - cur);
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
   502
			cname = PyBytes_FromStringAndSize(cpos + 1,
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   503
							   flen - (cpos - cur) - 1);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   504
			if (!fname || !cname ||
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   505
			    PyDict_SetItem(cmap, fname, cname) == -1 ||
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   506
			    PyDict_SetItem(dmap, fname, entry) == -1)
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   507
				goto quit;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   508
			Py_DECREF(cname);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   509
		} else {
11361
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
   510
			fname = PyBytes_FromStringAndSize(cur, flen);
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   511
			if (!fname ||
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   512
			    PyDict_SetItem(dmap, fname, entry) == -1)
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   513
				goto quit;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   514
		}
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   515
		Py_DECREF(fname);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   516
		Py_DECREF(entry);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   517
		fname = cname = entry = NULL;
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
   518
		pos += flen;
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   519
	}
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   520
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   521
	ret = parents;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   522
	Py_INCREF(ret);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   523
quit:
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   524
	Py_XDECREF(fname);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   525
	Py_XDECREF(cname);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   526
	Py_XDECREF(entry);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   527
	Py_XDECREF(parents);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   528
	return ret;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   529
}
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
   530
16955
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   531
/*
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   532
 * Efficiently pack a dirstate object into its on-disk format.
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   533
 */
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   534
static PyObject *pack_dirstate(PyObject *self, PyObject *args)
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   535
{
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   536
	PyObject *packobj = NULL;
21806
05bd2667df4d pack_dirstate: in C version, for invalidation set dict to what we write to disk
Siddharth Agarwal <sid0@fb.com>
parents: 21730
diff changeset
   537
	PyObject *map, *copymap, *pl, *mtime_unset = NULL;
16955
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   538
	Py_ssize_t nbytes, pos, l;
23946
f3e94aa6e182 parsers: don't leak a tuple in pack_dirstate
Augie Fackler <augie@google.com>
parents: 23945
diff changeset
   539
	PyObject *k, *v = NULL, *pn;
16955
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   540
	char *p, *s;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   541
	double now;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   542
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   543
	if (!PyArg_ParseTuple(args, "O!O!Od:pack_dirstate",
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   544
			      &PyDict_Type, &map, &PyDict_Type, &copymap,
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   545
			      &pl, &now))
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   546
		return NULL;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   547
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   548
	if (!PySequence_Check(pl) || PySequence_Size(pl) != 2) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   549
		PyErr_SetString(PyExc_TypeError, "expected 2-element sequence");
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   550
		return NULL;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   551
	}
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   552
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   553
	/* Figure out how much we need to allocate. */
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   554
	for (nbytes = 40, pos = 0; PyDict_Next(map, &pos, &k, &v);) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   555
		PyObject *c;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   556
		if (!PyString_Check(k)) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   557
			PyErr_SetString(PyExc_TypeError, "expected string key");
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   558
			goto bail;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   559
		}
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   560
		nbytes += PyString_GET_SIZE(k) + 17;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   561
		c = PyDict_GetItem(copymap, k);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   562
		if (c) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   563
			if (!PyString_Check(c)) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   564
				PyErr_SetString(PyExc_TypeError,
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   565
						"expected string key");
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   566
				goto bail;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   567
			}
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   568
			nbytes += PyString_GET_SIZE(c) + 1;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   569
		}
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   570
	}
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   571
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   572
	packobj = PyString_FromStringAndSize(NULL, nbytes);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   573
	if (packobj == NULL)
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   574
		goto bail;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   575
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   576
	p = PyString_AS_STRING(packobj);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   577
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   578
	pn = PySequence_ITEM(pl, 0);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   579
	if (PyString_AsStringAndSize(pn, &s, &l) == -1 || l != 20) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   580
		PyErr_SetString(PyExc_TypeError, "expected a 20-byte hash");
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   581
		goto bail;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   582
	}
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   583
	memcpy(p, s, l);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   584
	p += 20;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   585
	pn = PySequence_ITEM(pl, 1);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   586
	if (PyString_AsStringAndSize(pn, &s, &l) == -1 || l != 20) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   587
		PyErr_SetString(PyExc_TypeError, "expected a 20-byte hash");
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   588
		goto bail;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   589
	}
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   590
	memcpy(p, s, l);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   591
	p += 20;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   592
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   593
	for (pos = 0; PyDict_Next(map, &pos, &k, &v); ) {
21809
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   594
		dirstateTupleObject *tuple;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   595
		char state;
16955
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   596
		uint32_t mode, size, mtime;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   597
		Py_ssize_t len, l;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   598
		PyObject *o;
21809
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   599
		char *t;
16955
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   600
21809
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   601
		if (!dirstate_tuple_check(v)) {
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   602
			PyErr_SetString(PyExc_TypeError,
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   603
					"expected a dirstate tuple");
16955
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   604
			goto bail;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   605
		}
21809
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   606
		tuple = (dirstateTupleObject *)v;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   607
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   608
		state = tuple->state;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   609
		mode = tuple->mode;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   610
		size = tuple->size;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   611
		mtime = tuple->mtime;
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   612
		if (state == 'n' && mtime == (uint32_t)now) {
18567
194e63c1ccb9 dirstate: move pure python dirstate packing to pure/parsers.py
Siddharth Agarwal <sid0@fb.com>
parents: 18504
diff changeset
   613
			/* See pure/parsers.py:pack_dirstate for why we do
194e63c1ccb9 dirstate: move pure python dirstate packing to pure/parsers.py
Siddharth Agarwal <sid0@fb.com>
parents: 18504
diff changeset
   614
			 * this. */
21806
05bd2667df4d pack_dirstate: in C version, for invalidation set dict to what we write to disk
Siddharth Agarwal <sid0@fb.com>
parents: 21730
diff changeset
   615
			mtime = -1;
21809
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   616
			mtime_unset = (PyObject *)make_dirstate_tuple(
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   617
				state, mode, size, mtime);
21806
05bd2667df4d pack_dirstate: in C version, for invalidation set dict to what we write to disk
Siddharth Agarwal <sid0@fb.com>
parents: 21730
diff changeset
   618
			if (!mtime_unset)
16955
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   619
				goto bail;
21806
05bd2667df4d pack_dirstate: in C version, for invalidation set dict to what we write to disk
Siddharth Agarwal <sid0@fb.com>
parents: 21730
diff changeset
   620
			if (PyDict_SetItem(map, k, mtime_unset) == -1)
05bd2667df4d pack_dirstate: in C version, for invalidation set dict to what we write to disk
Siddharth Agarwal <sid0@fb.com>
parents: 21730
diff changeset
   621
				goto bail;
05bd2667df4d pack_dirstate: in C version, for invalidation set dict to what we write to disk
Siddharth Agarwal <sid0@fb.com>
parents: 21730
diff changeset
   622
			Py_DECREF(mtime_unset);
05bd2667df4d pack_dirstate: in C version, for invalidation set dict to what we write to disk
Siddharth Agarwal <sid0@fb.com>
parents: 21730
diff changeset
   623
			mtime_unset = NULL;
16955
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   624
		}
21809
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
   625
		*p++ = state;
16955
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   626
		putbe32(mode, p);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   627
		putbe32(size, p + 4);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   628
		putbe32(mtime, p + 8);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   629
		t = p + 12;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   630
		p += 16;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   631
		len = PyString_GET_SIZE(k);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   632
		memcpy(p, PyString_AS_STRING(k), len);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   633
		p += len;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   634
		o = PyDict_GetItem(copymap, k);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   635
		if (o) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   636
			*p++ = '\0';
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   637
			l = PyString_GET_SIZE(o);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   638
			memcpy(p, PyString_AS_STRING(o), l);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   639
			p += l;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   640
			len += l + 1;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   641
		}
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   642
		putbe32((uint32_t)len, t);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   643
	}
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   644
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   645
	pos = p - PyString_AS_STRING(packobj);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   646
	if (pos != nbytes) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   647
		PyErr_Format(PyExc_SystemError, "bad dirstate size: %ld != %ld",
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   648
                             (long)pos, (long)nbytes);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   649
		goto bail;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   650
	}
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   651
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   652
	return packobj;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   653
bail:
21806
05bd2667df4d pack_dirstate: in C version, for invalidation set dict to what we write to disk
Siddharth Agarwal <sid0@fb.com>
parents: 21730
diff changeset
   654
	Py_XDECREF(mtime_unset);
16955
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   655
	Py_XDECREF(packobj);
23946
f3e94aa6e182 parsers: don't leak a tuple in pack_dirstate
Augie Fackler <augie@google.com>
parents: 23945
diff changeset
   656
	Py_XDECREF(v);
16955
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   657
	return NULL;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   658
}
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
   659
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   660
/*
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   661
 * 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
   662
 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   663
 * Positive value is index of the next node in the trie
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   664
 * Negative value is a leaf: -(rev + 1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   665
 * Zero is empty
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   666
 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   667
typedef struct {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   668
	int children[16];
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   669
} nodetree;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   670
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   671
/*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   672
 * This class has two behaviours.
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   673
 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   674
 * When used in a list-like way (with integer keys), we decode an
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   675
 * entry in a RevlogNG index file on demand. Our last entry is a
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   676
 * sentinel, always a nullid.  We have limited support for
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   677
 * integer-keyed insert and delete, only at elements right before the
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   678
 * sentinel.
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   679
 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   680
 * 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
   681
 * 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
   682
 */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   683
typedef struct {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   684
	PyObject_HEAD
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   685
	/* Type-specific fields go here. */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   686
	PyObject *data;        /* raw bytes of index */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   687
	PyObject **cache;      /* cached tuples */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   688
	const char **offsets;  /* populated on demand */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   689
	Py_ssize_t raw_length; /* original number of elements */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   690
	Py_ssize_t length;     /* current number of elements */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   691
	PyObject *added;       /* populated on demand */
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   692
	PyObject *headrevs;    /* cache, invalidated on changes */
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
   693
	PyObject *filteredrevs;/* filtered revs set */
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   694
	nodetree *nt;          /* base-16 trie */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   695
	int ntlength;          /* # nodes in use */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   696
	int ntcapacity;        /* # nodes allocated */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   697
	int ntdepth;           /* maximum depth of tree */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   698
	int ntsplits;          /* # splits performed */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   699
	int ntrev;             /* last rev scanned */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   700
	int ntlookups;         /* # lookups */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   701
	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
   702
	int inlined;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   703
} indexObject;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   704
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   705
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
   706
{
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   707
	if (self->added == NULL)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   708
		return self->length;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   709
	return self->length + PyList_GET_SIZE(self->added);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   710
}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   711
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   712
static PyObject *nullentry;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   713
static const char nullid[20];
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   714
22401
9ba8a93e55f5 parsers: ensure correct return type for inline_scan
Henrik Stuart <hg@hstuart.dk>
parents: 22400
diff changeset
   715
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
   716
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   717
#if LONG_MAX == 0x7fffffffL
16393
ee163a9cf37c util.h: more Python 2.4 fixes
Matt Mackall <mpm@selenic.com>
parents: 16385
diff changeset
   718
static char *tuple_format = "Kiiiiiis#";
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   719
#else
16393
ee163a9cf37c util.h: more Python 2.4 fixes
Matt Mackall <mpm@selenic.com>
parents: 16385
diff changeset
   720
static char *tuple_format = "kiiiiiis#";
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   721
#endif
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   722
16863
bbedef66c6f3 parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents: 16787
diff changeset
   723
/* 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
   724
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
   725
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   726
/*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   727
 * 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
   728
 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   729
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
   730
{
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   731
	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
   732
		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
   733
			self->offsets = malloc(self->raw_length *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   734
					       sizeof(*self->offsets));
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   735
			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
   736
				return (const char *)PyErr_NoMemory();
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   737
			inline_scan(self, self->offsets);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   738
		}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   739
		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
   740
	}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   741
16863
bbedef66c6f3 parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents: 16787
diff changeset
   742
	return PyString_AS_STRING(self->data) + pos * v1_hdrsize;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   743
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   744
25311
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
   745
static inline void index_get_parents(indexObject *self, Py_ssize_t rev,
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
   746
				int *ps)
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
   747
{
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
   748
	if (rev >= self->length - 1) {
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
   749
		PyObject *tuple = PyList_GET_ITEM(self->added,
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
   750
						  rev - self->length + 1);
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
   751
		ps[0] = (int)PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, 5));
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
   752
		ps[1] = (int)PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, 6));
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
   753
	} else {
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
   754
		const char *data = index_deref(self, rev);
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
   755
		ps[0] = getbe32(data + 24);
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
   756
		ps[1] = getbe32(data + 28);
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
   757
	}
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
   758
}
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
   759
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
   760
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   761
/*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   762
 * 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
   763
 *    6 bytes: offset
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   764
 *    2 bytes: flags
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   765
 *    4 bytes: compressed length
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   766
 *    4 bytes: uncompressed length
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   767
 *    4 bytes: base revision
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   768
 *    4 bytes: link revision
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   769
 *    4 bytes: parent 1 revision
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   770
 *    4 bytes: parent 2 revision
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   771
 *   32 bytes: nodeid (only 20 bytes used)
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   772
 */
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   773
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
   774
{
7154
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   775
	uint64_t offset_flags;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   776
	int comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2;
7154
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   777
	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
   778
	const char *data;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   779
	Py_ssize_t length = index_length(self);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   780
	PyObject *entry;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   781
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   782
	if (pos < 0)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   783
		pos += length;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   784
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   785
	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
   786
		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
   787
		return NULL;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   788
	}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   789
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   790
	if (pos == length - 1) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   791
		Py_INCREF(nullentry);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   792
		return nullentry;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   793
	}
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   794
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   795
	if (pos >= self->length - 1) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   796
		PyObject *obj;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   797
		obj = PyList_GET_ITEM(self->added, pos - self->length + 1);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   798
		Py_INCREF(obj);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   799
		return obj;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   800
	}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   801
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   802
	if (self->cache) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   803
		if (self->cache[pos]) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   804
			Py_INCREF(self->cache[pos]);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   805
			return self->cache[pos];
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   806
		}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   807
	} else {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   808
		self->cache = calloc(self->raw_length, sizeof(PyObject *));
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   809
		if (self->cache == NULL)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   810
			return PyErr_NoMemory();
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   811
	}
7190
aecea6934fdd Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7186
diff changeset
   812
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   813
	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
   814
	if (data == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   815
		return NULL;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   816
16437
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
   817
	offset_flags = getbe32(data + 4);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   818
	if (pos == 0) /* mask out version number for the first entry */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   819
		offset_flags &= 0xFFFF;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   820
	else {
16437
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
   821
		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
   822
		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
   823
	}
7154
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
   824
16437
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
   825
	comp_len = getbe32(data + 8);
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
   826
	uncomp_len = getbe32(data + 12);
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
   827
	base_rev = getbe32(data + 16);
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
   828
	link_rev = getbe32(data + 20);
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
   829
	parent_1 = getbe32(data + 24);
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
   830
	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
   831
	c_node_id = data + 32;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   832
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   833
	entry = Py_BuildValue(tuple_format, offset_flags, comp_len,
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
   834
			      uncomp_len, base_rev, link_rev,
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
   835
			      parent_1, parent_2, c_node_id, 20);
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
   836
19726
b3c8c6f2b5c1 parsers: use Py_INCREF safely
Bryan O'Sullivan <bryano@fb.com>
parents: 19725
diff changeset
   837
	if (entry) {
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   838
		PyObject_GC_UnTrack(entry);
19726
b3c8c6f2b5c1 parsers: use Py_INCREF safely
Bryan O'Sullivan <bryano@fb.com>
parents: 19725
diff changeset
   839
		Py_INCREF(entry);
b3c8c6f2b5c1 parsers: use Py_INCREF safely
Bryan O'Sullivan <bryano@fb.com>
parents: 19725
diff changeset
   840
	}
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   841
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   842
	self->cache[pos] = entry;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   843
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   844
	return entry;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   845
}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   846
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   847
/*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   848
 * Return the 20-byte SHA of the node corresponding to the given rev.
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   849
 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   850
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
   851
{
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   852
	Py_ssize_t length = index_length(self);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   853
	const char *data;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   854
16664
5bc6edf71b39 parsers: ensure that nullid is always present in the radix tree
Bryan O'Sullivan <bryano@fb.com>
parents: 16663
diff changeset
   855
	if (pos == length - 1 || pos == INT_MAX)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   856
		return nullid;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   857
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   858
	if (pos >= length)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   859
		return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   860
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   861
	if (pos >= self->length - 1) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   862
		PyObject *tuple, *str;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   863
		tuple = PyList_GET_ITEM(self->added, pos - self->length + 1);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   864
		str = PyTuple_GetItem(tuple, 7);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   865
		return str ? PyString_AS_STRING(str) : NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   866
	}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   867
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   868
	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
   869
	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
   870
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   871
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   872
static int nt_insert(indexObject *self, const char *node, int rev);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   873
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   874
static int node_check(PyObject *obj, char **node, Py_ssize_t *nodelen)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   875
{
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   876
	if (PyString_AsStringAndSize(obj, node, nodelen) == -1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   877
		return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   878
	if (*nodelen == 20)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   879
		return 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   880
	PyErr_SetString(PyExc_ValueError, "20-byte hash required");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   881
	return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   882
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   883
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   884
static PyObject *index_insert(indexObject *self, PyObject *args)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   885
{
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   886
	PyObject *obj;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   887
	char *node;
22604
5e0d1478db8e parsers: fix Py2.4 argument parsing issue
Matt Mackall <mpm@selenic.com>
parents: 22540
diff changeset
   888
	int index;
5e0d1478db8e parsers: fix Py2.4 argument parsing issue
Matt Mackall <mpm@selenic.com>
parents: 22540
diff changeset
   889
	Py_ssize_t len, nodelen;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   890
22604
5e0d1478db8e parsers: fix Py2.4 argument parsing issue
Matt Mackall <mpm@selenic.com>
parents: 22540
diff changeset
   891
	if (!PyArg_ParseTuple(args, "iO", &index, &obj))
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   892
		return NULL;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   893
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   894
	if (!PyTuple_Check(obj) || PyTuple_GET_SIZE(obj) != 8) {
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   895
		PyErr_SetString(PyExc_TypeError, "8-tuple required");
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   896
		return NULL;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   897
	}
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
   898
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   899
	if (node_check(PyTuple_GET_ITEM(obj, 7), &node, &nodelen) == -1)
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   900
		return NULL;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   901
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   902
	len = index_length(self);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   903
22604
5e0d1478db8e parsers: fix Py2.4 argument parsing issue
Matt Mackall <mpm@selenic.com>
parents: 22540
diff changeset
   904
	if (index < 0)
5e0d1478db8e parsers: fix Py2.4 argument parsing issue
Matt Mackall <mpm@selenic.com>
parents: 22540
diff changeset
   905
		index += len;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   906
22604
5e0d1478db8e parsers: fix Py2.4 argument parsing issue
Matt Mackall <mpm@selenic.com>
parents: 22540
diff changeset
   907
	if (index != len - 1) {
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   908
		PyErr_SetString(PyExc_IndexError,
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   909
				"insert only supported at index -1");
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   910
		return NULL;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   911
	}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   912
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   913
	if (self->added == NULL) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   914
		self->added = PyList_New(0);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   915
		if (self->added == NULL)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   916
			return NULL;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   917
	}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   918
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   919
	if (PyList_Append(self->added, obj) == -1)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   920
		return NULL;
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
   921
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   922
	if (self->nt)
22604
5e0d1478db8e parsers: fix Py2.4 argument parsing issue
Matt Mackall <mpm@selenic.com>
parents: 22540
diff changeset
   923
		nt_insert(self, node, index);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   924
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   925
	Py_CLEAR(self->headrevs);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   926
	Py_RETURN_NONE;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   927
}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
   928
16370
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
   929
static void _index_clearcaches(indexObject *self)
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
   930
{
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
   931
	if (self->cache) {
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
   932
		Py_ssize_t i;
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
   933
16732
277e2acb7e5c parsers: use Py_CLEAR where appropriate
Bryan O'Sullivan <bryano@fb.com>
parents: 16699
diff changeset
   934
		for (i = 0; i < self->raw_length; i++)
277e2acb7e5c parsers: use Py_CLEAR where appropriate
Bryan O'Sullivan <bryano@fb.com>
parents: 16699
diff changeset
   935
			Py_CLEAR(self->cache[i]);
16370
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
   936
		free(self->cache);
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
   937
		self->cache = NULL;
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
   938
	}
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
   939
	if (self->offsets) {
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
   940
		free(self->offsets);
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
   941
		self->offsets = NULL;
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
   942
	}
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   943
	if (self->nt) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   944
		free(self->nt);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   945
		self->nt = NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   946
	}
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   947
	Py_CLEAR(self->headrevs);
16370
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
   948
}
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
   949
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
   950
static PyObject *index_clearcaches(indexObject *self)
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
   951
{
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
   952
	_index_clearcaches(self);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   953
	self->ntlength = self->ntcapacity = 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   954
	self->ntdepth = self->ntsplits = 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   955
	self->ntrev = -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   956
	self->ntlookups = self->ntmisses = 0;
16370
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
   957
	Py_RETURN_NONE;
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
   958
}
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
   959
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   960
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
   961
{
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   962
	PyObject *obj = PyDict_New();
23948
bd307b462ce2 parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents: 23947
diff changeset
   963
	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
   964
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   965
	if (obj == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   966
		return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   967
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   968
#define istat(__n, __d) \
23948
bd307b462ce2 parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents: 23947
diff changeset
   969
	t = PyInt_FromSsize_t(self->__n); \
bd307b462ce2 parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents: 23947
diff changeset
   970
	if (!t) \
bd307b462ce2 parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents: 23947
diff changeset
   971
		goto bail; \
bd307b462ce2 parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents: 23947
diff changeset
   972
	if (PyDict_SetItemString(obj, __d, t) == -1) \
bd307b462ce2 parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents: 23947
diff changeset
   973
		goto bail; \
bd307b462ce2 parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents: 23947
diff changeset
   974
	Py_DECREF(t);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   975
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   976
	if (self->added) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   977
		Py_ssize_t len = PyList_GET_SIZE(self->added);
23948
bd307b462ce2 parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents: 23947
diff changeset
   978
		t = PyInt_FromSsize_t(len);
bd307b462ce2 parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents: 23947
diff changeset
   979
		if (!t)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   980
			goto bail;
23948
bd307b462ce2 parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents: 23947
diff changeset
   981
		if (PyDict_SetItemString(obj, "index entries added", t) == -1)
bd307b462ce2 parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents: 23947
diff changeset
   982
			goto bail;
bd307b462ce2 parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents: 23947
diff changeset
   983
		Py_DECREF(t);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   984
	}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   985
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   986
	if (self->raw_length != self->length - 1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   987
		istat(raw_length, "revs on disk");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   988
	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
   989
	istat(ntcapacity, "node trie capacity");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   990
	istat(ntdepth, "node trie depth");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   991
	istat(ntlength, "node trie count");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   992
	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
   993
	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
   994
	istat(ntrev, "node trie last rev scanned");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   995
	istat(ntsplits, "node trie splits");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   996
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   997
#undef istat
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   998
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
   999
	return obj;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1000
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1001
bail:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1002
	Py_XDECREF(obj);
23948
bd307b462ce2 parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents: 23947
diff changeset
  1003
	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
  1004
	return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1005
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1006
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1007
/*
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1008
 * 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
  1009
 * the cached copy.
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1010
 */
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1011
static PyObject *list_copy(PyObject *list)
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1012
{
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1013
	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
  1014
	PyObject *newlist = PyList_New(len);
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1015
	Py_ssize_t i;
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1016
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1017
	if (newlist == NULL)
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1018
		return NULL;
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1019
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1020
	for (i = 0; i < len; i++) {
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1021
		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
  1022
		Py_INCREF(obj);
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1023
		PyList_SET_ITEM(newlist, i, obj);
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1024
	}
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1025
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1026
	return newlist;
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1027
}
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1028
23073
5715c93cb854 parsers: use 'k' format for Py_BuildValue instead of 'n' because Python 2.4
Mads Kiilerich <madski@unity3d.com>
parents: 22778
diff changeset
  1029
/* arg should be Py_ssize_t but Python 2.4 do not support the n format */
5715c93cb854 parsers: use 'k' format for Py_BuildValue instead of 'n' because Python 2.4
Mads Kiilerich <madski@unity3d.com>
parents: 22778
diff changeset
  1030
static int check_filter(PyObject *filter, unsigned long arg) {
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1031
	if (filter) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1032
		PyObject *arglist, *result;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1033
		int isfiltered;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1034
23073
5715c93cb854 parsers: use 'k' format for Py_BuildValue instead of 'n' because Python 2.4
Mads Kiilerich <madski@unity3d.com>
parents: 22778
diff changeset
  1035
		arglist = Py_BuildValue("(k)", arg);
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1036
		if (!arglist) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1037
			return -1;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1038
		}
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1039
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1040
		result = PyEval_CallObject(filter, arglist);
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1041
		Py_DECREF(arglist);
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1042
		if (!result) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1043
			return -1;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1044
		}
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1045
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1046
		/* 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
  1047
		 * 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
  1048
		isfiltered = PyObject_IsTrue(result);
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1049
		Py_DECREF(result);
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1050
		return isfiltered;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1051
	} else {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1052
		return 0;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1053
	}
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1054
}
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1055
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1056
static Py_ssize_t add_roots_get_min(indexObject *self, PyObject *list,
24499
90db70de6f9c parsers.c: avoid implicit conversion loses integer warnings
André Sintzoff <andre.sintzoff@gmail.com>
parents: 24443
diff changeset
  1057
                                    Py_ssize_t marker, char *phases)
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1058
{
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1059
	PyObject *iter = NULL;
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1060
	PyObject *iter_item = NULL;
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1061
	Py_ssize_t min_idx = index_length(self) + 1;
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1062
	long iter_item_long;
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1063
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1064
	if (PyList_GET_SIZE(list) != 0) {
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1065
		iter = PyObject_GetIter(list);
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1066
		if (iter == NULL)
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1067
			return -2;
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1068
		while ((iter_item = PyIter_Next(iter)))
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1069
		{
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1070
			iter_item_long = PyInt_AS_LONG(iter_item);
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1071
			Py_DECREF(iter_item);
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1072
			if (iter_item_long < min_idx)
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1073
				min_idx = iter_item_long;
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1074
			phases[iter_item_long] = marker;
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1075
		}
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1076
		Py_DECREF(iter);
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1077
	}
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1078
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1079
	return min_idx;
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1080
}
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1081
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1082
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
  1083
                                          int parent_2, Py_ssize_t i)
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1084
{
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1085
	if (parent_1 >= 0 && phases[parent_1] > phases[i])
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1086
		phases[i] = phases[parent_1];
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1087
	if (parent_2 >= 0 && phases[parent_2] > phases[i])
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1088
		phases[i] = phases[parent_2];
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1089
}
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1090
25190
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1091
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
  1092
{
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1093
	PyObject *roots = Py_None;
25190
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1094
	PyObject *ret = NULL;
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1095
	PyObject *phaseslist = NULL;
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1096
	PyObject *phaseroots = NULL;
25190
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1097
	PyObject *phaseset = NULL;
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1098
	PyObject *phasessetlist = NULL;
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1099
	Py_ssize_t len = index_length(self) - 1;
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1100
	Py_ssize_t numphase = 0;
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1101
	Py_ssize_t minrevallphases = 0;
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1102
	Py_ssize_t minrevphase = 0;
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1103
	Py_ssize_t i = 0;
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1104
	char *phases = NULL;
25190
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1105
	long phase;
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1106
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1107
	if (!PyArg_ParseTuple(args, "O", &roots))
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1108
		goto release_none;
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1109
	if (roots == NULL || !PyList_Check(roots))
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1110
		goto release_none;
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1111
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1112
	phases = calloc(len, 1); /* phase per rev: {0: public, 1: draft, 2: secret} */
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1113
	if (phases == NULL)
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1114
		goto release_none;
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1115
	/* Put the phase information of all the roots in phases */
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1116
	numphase = PyList_GET_SIZE(roots)+1;
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1117
	minrevallphases = len + 1;
25190
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1118
	phasessetlist = PyList_New(numphase);
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1119
	if (phasessetlist == NULL)
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1120
		goto release_none;
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1121
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1122
	PyList_SET_ITEM(phasessetlist, 0, Py_None);
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1123
	Py_INCREF(Py_None);
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1124
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1125
	for (i = 0; i < numphase-1; i++) {
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1126
		phaseroots = PyList_GET_ITEM(roots, i);
25190
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1127
		phaseset = PySet_New(NULL);
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1128
		if (phaseset == NULL)
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1129
			goto release_phasesetlist;
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1130
		PyList_SET_ITEM(phasessetlist, i+1, phaseset);
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1131
		if (!PyList_Check(phaseroots))
25190
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1132
			goto release_phasesetlist;
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1133
		minrevphase = add_roots_get_min(self, phaseroots, i+1, phases);
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1134
		if (minrevphase == -2) /* Error from add_roots_get_min */
25190
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1135
			goto release_phasesetlist;
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1136
		minrevallphases = MIN(minrevallphases, minrevphase);
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1137
	}
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1138
	/* Propagate the phase information from the roots to the revs */
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1139
	if (minrevallphases != -1) {
25312
ee02728dd5f9 parsers: simplify the code computing the phases
Laurent Charignon <lcharignon@fb.com>
parents: 25311
diff changeset
  1140
		int parents[2];
ee02728dd5f9 parsers: simplify the code computing the phases
Laurent Charignon <lcharignon@fb.com>
parents: 25311
diff changeset
  1141
		for (i = minrevallphases; i < len; i++) {
ee02728dd5f9 parsers: simplify the code computing the phases
Laurent Charignon <lcharignon@fb.com>
parents: 25311
diff changeset
  1142
			index_get_parents(self, i, parents);
ee02728dd5f9 parsers: simplify the code computing the phases
Laurent Charignon <lcharignon@fb.com>
parents: 25311
diff changeset
  1143
			set_phase_from_parents(phases, parents[0], parents[1], i);
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1144
		}
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1145
	}
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1146
	/* Transform phase list to a python list */
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1147
	phaseslist = PyList_New(len);
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1148
	if (phaseslist == NULL)
25190
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1149
		goto release_phasesetlist;
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1150
	for (i = 0; i < len; i++) {
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1151
		phase = phases[i];
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1152
		/* We only store the sets of phase for non public phase, the public phase
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1153
		 * is computed as a difference */
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1154
		if (phase != 0) {
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1155
			phaseset = PyList_GET_ITEM(phasessetlist, phase);
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1156
			PySet_Add(phaseset, PyInt_FromLong(i));
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1157
		}
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1158
		PyList_SET_ITEM(phaseslist, i, PyInt_FromLong(phase));
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1159
	}
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1160
	ret = PyList_New(2);
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1161
	if (ret == NULL)
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1162
		goto release_phaseslist;
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1163
25190
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1164
	PyList_SET_ITEM(ret, 0, phaseslist);
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1165
	PyList_SET_ITEM(ret, 1, phasessetlist);
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1166
	/* We don't release phaseslist and phasessetlist as we return them to
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1167
	 * python */
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1168
	goto release_phases;
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1169
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1170
release_phaseslist:
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1171
	Py_XDECREF(phaseslist);
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1172
release_phasesetlist:
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1173
	Py_XDECREF(phasessetlist);
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1174
release_phases:
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1175
	free(phases);
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1176
release_none:
25190
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  1177
	return ret;
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1178
}
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
  1179
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1180
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
  1181
{
25297
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
  1182
	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
  1183
	char *nothead = NULL;
22540
9a860ac8c216 parsers: fix uninitialize variable warning
David Soria Parra <davidsp@fb.com>
parents: 22484
diff changeset
  1184
	PyObject *heads = NULL;
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1185
	PyObject *filter = NULL;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1186
	PyObject *filteredrevs = Py_None;
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1187
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1188
	if (!PyArg_ParseTuple(args, "|O", &filteredrevs)) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1189
		return NULL;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1190
	}
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1191
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1192
	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
  1193
		return list_copy(self->headrevs);
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1194
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1195
	Py_DECREF(self->filteredrevs);
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1196
	self->filteredrevs = filteredrevs;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1197
	Py_INCREF(filteredrevs);
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1198
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1199
	if (filteredrevs != Py_None) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1200
		filter = PyObject_GetAttrString(filteredrevs, "__contains__");
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1201
		if (!filter) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1202
			PyErr_SetString(PyExc_TypeError,
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1203
				"filteredrevs has no attribute __contains__");
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1204
			goto bail;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1205
		}
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1206
	}
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1207
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1208
	len = index_length(self) - 1;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1209
	heads = PyList_New(0);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1210
	if (heads == NULL)
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1211
		goto bail;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1212
	if (len == 0) {
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1213
		PyObject *nullid = PyInt_FromLong(-1);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1214
		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
  1215
			Py_XDECREF(nullid);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1216
			goto bail;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1217
		}
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1218
		goto done;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1219
	}
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1220
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1221
	nothead = calloc(len, 1);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1222
	if (nothead == NULL)
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1223
		goto bail;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1224
25297
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
  1225
	for (i = 0; i < len; i++) {
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
  1226
		int isfiltered;
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
  1227
		int parents[2];
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1228
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1229
		isfiltered = check_filter(filter, i);
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1230
		if (isfiltered == -1) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1231
			PyErr_SetString(PyExc_TypeError,
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1232
				"unable to check filter");
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1233
			goto bail;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1234
		}
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1235
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1236
		if (isfiltered) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1237
			nothead[i] = 1;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1238
			continue;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1239
		}
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1240
25297
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
  1241
		index_get_parents(self, i, parents);
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
  1242
		for (j = 0; j < 2; j++) {
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
  1243
			if (parents[j] >= 0)
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
  1244
				nothead[parents[j]] = 1;
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1245
		}
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1246
	}
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1247
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1248
	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
  1249
		PyObject *head;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1250
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1251
		if (nothead[i])
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1252
			continue;
22400
888bc106de83 parsers: fix typing issue when constructing Python integer object
Henrik Stuart <hg@hstuart.dk>
parents: 22399
diff changeset
  1253
		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
  1254
		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
  1255
			Py_XDECREF(head);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1256
			goto bail;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1257
		}
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1258
	}
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1259
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1260
done:
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1261
	self->headrevs = heads;
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1262
	Py_XDECREF(filter);
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1263
	free(nothead);
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  1264
	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
  1265
bail:
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  1266
	Py_XDECREF(filter);
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1267
	Py_XDECREF(heads);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1268
	free(nothead);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1269
	return NULL;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1270
}
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
  1271
16618
6bae941b58ad parsers: change the type of nt_level
Bryan O'Sullivan <bryano@fb.com>
parents: 16617
diff changeset
  1272
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
  1273
{
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1274
	int v = node[level>>1];
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1275
	if (!(level & 1))
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1276
		v >>= 4;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1277
	return v & 0xf;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1278
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1279
16616
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
  1280
/*
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
  1281
 * Return values:
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
  1282
 *
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
  1283
 *   -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
  1284
 *   -2: not found
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
  1285
 * rest: valid rev
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
  1286
 */
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1287
static int nt_find(indexObject *self, const char *node, Py_ssize_t nodelen,
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1288
		   int hex)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1289
{
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1290
	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
  1291
	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
  1292
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1293
	if (nodelen == 20 && node[0] == '\0' && memcmp(node, nullid, 20) == 0)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1294
		return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1295
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1296
	if (self->nt == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1297
		return -2;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1298
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1299
	if (hex)
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1300
		maxlevel = nodelen > 40 ? 40 : (int)nodelen;
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1301
	else
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1302
		maxlevel = nodelen > 20 ? 40 : ((int)nodelen * 2);
16641
e6dfbc5df76f parsers: use the correct maximum radix tree depth
Bryan O'Sullivan <bryano@fb.com>
parents: 16604
diff changeset
  1303
e6dfbc5df76f parsers: use the correct maximum radix tree depth
Bryan O'Sullivan <bryano@fb.com>
parents: 16604
diff changeset
  1304
	for (level = off = 0; level < maxlevel; level++) {
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1305
		int k = getnybble(node, level);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1306
		nodetree *n = &self->nt[off];
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1307
		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
  1308
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1309
		if (v < 0) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1310
			const char *n;
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1311
			Py_ssize_t i;
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1312
24879
b3142ea2a0d4 parsers: avoid signed integer overflow in calculation of leaf-node index
Yuya Nishihara <yuya@tcha.org>
parents: 24736
diff changeset
  1313
			v = -(v + 1);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1314
			n = index_node(self, v);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1315
			if (n == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1316
				return -2;
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1317
			for (i = level; i < maxlevel; i++)
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1318
				if (getnybble(node, i) != nt_level(n, i))
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1319
					return -2;
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1320
			return v;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1321
		}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1322
		if (v == 0)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1323
			return -2;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1324
		off = v;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1325
	}
16616
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
  1326
	/* 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
  1327
	return -4;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1328
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1329
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1330
static int nt_new(indexObject *self)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1331
{
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1332
	if (self->ntlength == self->ntcapacity) {
24623
2262d7bc469e parsers: check for memory allocation overflows more carefully
Bryan O'Sullivan <bryano@fb.com>
parents: 24622
diff changeset
  1333
		if (self->ntcapacity >= INT_MAX / (sizeof(nodetree) * 2)) {
2262d7bc469e parsers: check for memory allocation overflows more carefully
Bryan O'Sullivan <bryano@fb.com>
parents: 24622
diff changeset
  1334
			PyErr_SetString(PyExc_MemoryError,
2262d7bc469e parsers: check for memory allocation overflows more carefully
Bryan O'Sullivan <bryano@fb.com>
parents: 24622
diff changeset
  1335
					"overflow in nt_new");
2262d7bc469e parsers: check for memory allocation overflows more carefully
Bryan O'Sullivan <bryano@fb.com>
parents: 24622
diff changeset
  1336
			return -1;
2262d7bc469e parsers: check for memory allocation overflows more carefully
Bryan O'Sullivan <bryano@fb.com>
parents: 24622
diff changeset
  1337
		}
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1338
		self->ntcapacity *= 2;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1339
		self->nt = realloc(self->nt,
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1340
				   self->ntcapacity * sizeof(nodetree));
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1341
		if (self->nt == NULL) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1342
			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
  1343
			return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1344
		}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1345
		memset(&self->nt[self->ntlength], 0,
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1346
		       sizeof(nodetree) * (self->ntcapacity - self->ntlength));
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1347
	}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1348
	return self->ntlength++;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1349
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1350
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1351
static int nt_insert(indexObject *self, const char *node, int rev)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1352
{
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1353
	int level = 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1354
	int off = 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1355
16641
e6dfbc5df76f parsers: use the correct maximum radix tree depth
Bryan O'Sullivan <bryano@fb.com>
parents: 16604
diff changeset
  1356
	while (level < 40) {
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1357
		int k = nt_level(node, level);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1358
		nodetree *n;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1359
		int v;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1360
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1361
		n = &self->nt[off];
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1362
		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
  1363
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1364
		if (v == 0) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1365
			n->children[k] = -rev - 1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1366
			return 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1367
		}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1368
		if (v < 0) {
24879
b3142ea2a0d4 parsers: avoid signed integer overflow in calculation of leaf-node index
Yuya Nishihara <yuya@tcha.org>
parents: 24736
diff changeset
  1369
			const char *oldnode = index_node(self, -(v + 1));
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1370
			int noff;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1371
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1372
			if (!oldnode || !memcmp(oldnode, node, 20)) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1373
				n->children[k] = -rev - 1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1374
				return 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1375
			}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1376
			noff = nt_new(self);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1377
			if (noff == -1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1378
				return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1379
			/* self->nt may have been changed by realloc */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1380
			self->nt[off].children[k] = noff;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1381
			off = noff;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1382
			n = &self->nt[off];
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1383
			n->children[nt_level(oldnode, ++level)] = v;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1384
			if (level > self->ntdepth)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1385
				self->ntdepth = level;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1386
			self->ntsplits += 1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1387
		} else {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1388
			level += 1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1389
			off = v;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1390
		}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1391
	}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1392
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1393
	return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1394
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1395
16615
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1396
static int nt_init(indexObject *self)
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1397
{
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1398
	if (self->nt == NULL) {
24623
2262d7bc469e parsers: check for memory allocation overflows more carefully
Bryan O'Sullivan <bryano@fb.com>
parents: 24622
diff changeset
  1399
		if (self->raw_length > INT_MAX / sizeof(nodetree)) {
20110
40b7c6e4b993 mercurial/parsers.c: fix compiler warning
Abhay Kadam <abhaykadam88@gmail.com>
parents: 19728
diff changeset
  1400
			PyErr_SetString(PyExc_ValueError, "overflow in nt_init");
40b7c6e4b993 mercurial/parsers.c: fix compiler warning
Abhay Kadam <abhaykadam88@gmail.com>
parents: 19728
diff changeset
  1401
			return -1;
40b7c6e4b993 mercurial/parsers.c: fix compiler warning
Abhay Kadam <abhaykadam88@gmail.com>
parents: 19728
diff changeset
  1402
		}
16615
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1403
		self->ntcapacity = self->raw_length < 4
20110
40b7c6e4b993 mercurial/parsers.c: fix compiler warning
Abhay Kadam <abhaykadam88@gmail.com>
parents: 19728
diff changeset
  1404
			? 4 : (int)self->raw_length / 2;
40b7c6e4b993 mercurial/parsers.c: fix compiler warning
Abhay Kadam <abhaykadam88@gmail.com>
parents: 19728
diff changeset
  1405
16615
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1406
		self->nt = calloc(self->ntcapacity, sizeof(nodetree));
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1407
		if (self->nt == NULL) {
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1408
			PyErr_NoMemory();
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1409
			return -1;
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1410
		}
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1411
		self->ntlength = 1;
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1412
		self->ntrev = (int)index_length(self) - 1;
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1413
		self->ntlookups = 1;
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1414
		self->ntmisses = 0;
16664
5bc6edf71b39 parsers: ensure that nullid is always present in the radix tree
Bryan O'Sullivan <bryano@fb.com>
parents: 16663
diff changeset
  1415
		if (nt_insert(self, nullid, INT_MAX) == -1)
5bc6edf71b39 parsers: ensure that nullid is always present in the radix tree
Bryan O'Sullivan <bryano@fb.com>
parents: 16663
diff changeset
  1416
			return -1;
16615
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1417
	}
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1418
	return 0;
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1419
}
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1420
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1421
/*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1422
 * Return values:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1423
 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1424
 *   -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
  1425
 *   -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
  1426
 * rest: valid rev
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1427
 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1428
static int index_find_node(indexObject *self,
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1429
			   const char *node, Py_ssize_t nodelen)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1430
{
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1431
	int rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1432
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1433
	self->ntlookups++;
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
  1434
	rev = nt_find(self, node, nodelen, 0);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1435
	if (rev >= -1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1436
		return rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1437
16615
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1438
	if (nt_init(self) == -1)
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
  1439
		return -3;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1440
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1441
	/*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1442
	 * 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
  1443
	 * 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
  1444
	 * 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
  1445
	 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1446
	 * 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
  1447
	 * 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
  1448
	 * 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
  1449
	 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1450
	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
  1451
		for (rev = self->ntrev - 1; rev >= 0; rev--) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1452
			const char *n = index_node(self, rev);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1453
			if (n == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1454
				return -2;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1455
			if (memcmp(node, n, nodelen > 20 ? 20 : nodelen) == 0) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1456
				if (nt_insert(self, n, rev) == -1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1457
					return -3;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1458
				break;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1459
			}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1460
		}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1461
	} else {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1462
		for (rev = self->ntrev - 1; rev >= 0; rev--) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1463
			const char *n = index_node(self, rev);
16614
1d800eb9ba52 parsers: update ntrev when we stop scanning
Bryan O'Sullivan <bryano@fb.com>
parents: 16597
diff changeset
  1464
			if (n == NULL) {
1d800eb9ba52 parsers: update ntrev when we stop scanning
Bryan O'Sullivan <bryano@fb.com>
parents: 16597
diff changeset
  1465
				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
  1466
				return -2;
16614
1d800eb9ba52 parsers: update ntrev when we stop scanning
Bryan O'Sullivan <bryano@fb.com>
parents: 16597
diff changeset
  1467
			}
1d800eb9ba52 parsers: update ntrev when we stop scanning
Bryan O'Sullivan <bryano@fb.com>
parents: 16597
diff changeset
  1468
			if (nt_insert(self, n, rev) == -1) {
1d800eb9ba52 parsers: update ntrev when we stop scanning
Bryan O'Sullivan <bryano@fb.com>
parents: 16597
diff changeset
  1469
				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
  1470
				return -3;
16614
1d800eb9ba52 parsers: update ntrev when we stop scanning
Bryan O'Sullivan <bryano@fb.com>
parents: 16597
diff changeset
  1471
			}
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1472
			if (memcmp(node, n, nodelen > 20 ? 20 : nodelen) == 0) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1473
				break;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1474
			}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1475
		}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1476
		self->ntrev = rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1477
	}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1478
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1479
	if (rev >= 0)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1480
		return rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1481
	return -2;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1482
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1483
25561
50a6c3c55db1 parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24879
diff changeset
  1484
static void raise_revlog_error(void)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1485
{
25561
50a6c3c55db1 parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24879
diff changeset
  1486
	PyObject *mod = NULL, *dict = NULL, *errclass = NULL;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1487
25561
50a6c3c55db1 parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24879
diff changeset
  1488
	mod = PyImport_ImportModule("mercurial.error");
50a6c3c55db1 parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24879
diff changeset
  1489
	if (mod == NULL) {
50a6c3c55db1 parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24879
diff changeset
  1490
		goto cleanup;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1491
	}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1492
25561
50a6c3c55db1 parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24879
diff changeset
  1493
	dict = PyModule_GetDict(mod);
50a6c3c55db1 parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24879
diff changeset
  1494
	if (dict == NULL) {
50a6c3c55db1 parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24879
diff changeset
  1495
		goto cleanup;
50a6c3c55db1 parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24879
diff changeset
  1496
	}
50a6c3c55db1 parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24879
diff changeset
  1497
	Py_INCREF(dict);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1498
25561
50a6c3c55db1 parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24879
diff changeset
  1499
	errclass = PyDict_GetItemString(dict, "RevlogError");
50a6c3c55db1 parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24879
diff changeset
  1500
	if (errclass == NULL) {
50a6c3c55db1 parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24879
diff changeset
  1501
		PyErr_SetString(PyExc_SystemError,
50a6c3c55db1 parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24879
diff changeset
  1502
				"could not find RevlogError");
50a6c3c55db1 parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24879
diff changeset
  1503
		goto cleanup;
50a6c3c55db1 parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24879
diff changeset
  1504
	}
50a6c3c55db1 parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24879
diff changeset
  1505
50a6c3c55db1 parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24879
diff changeset
  1506
	/* value of exception is ignored by callers */
50a6c3c55db1 parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24879
diff changeset
  1507
	PyErr_SetString(errclass, "RevlogError");
50a6c3c55db1 parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24879
diff changeset
  1508
50a6c3c55db1 parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24879
diff changeset
  1509
cleanup:
50a6c3c55db1 parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24879
diff changeset
  1510
	Py_XDECREF(dict);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1511
	Py_XDECREF(mod);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1512
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1513
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1514
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
  1515
{
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1516
	char *node;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1517
	Py_ssize_t nodelen;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1518
	int rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1519
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1520
	if (PyInt_Check(value))
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1521
		return index_get(self, PyInt_AS_LONG(value));
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1522
16679
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
  1523
	if (node_check(value, &node, &nodelen) == -1)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1524
		return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1525
	rev = index_find_node(self, node, nodelen);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1526
	if (rev >= -1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1527
		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
  1528
	if (rev == -2)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1529
		raise_revlog_error();
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1530
	return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1531
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1532
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1533
static int nt_partialmatch(indexObject *self, const char *node,
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1534
			   Py_ssize_t nodelen)
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1535
{
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1536
	int rev;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1537
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1538
	if (nt_init(self) == -1)
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1539
		return -3;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1540
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1541
	if (self->ntrev > 0) {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1542
		/* ensure that the radix tree is fully populated */
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1543
		for (rev = self->ntrev - 1; rev >= 0; rev--) {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1544
			const char *n = index_node(self, rev);
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1545
			if (n == NULL)
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1546
				return -2;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1547
			if (nt_insert(self, n, rev) == -1)
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1548
				return -3;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1549
		}
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1550
		self->ntrev = rev;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1551
	}
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1552
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1553
	return nt_find(self, node, nodelen, 1);
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1554
}
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1555
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1556
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
  1557
{
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1558
	const char *fullnode;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1559
	int nodelen;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1560
	char *node;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1561
	int rev, i;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1562
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1563
	if (!PyArg_ParseTuple(args, "s#", &node, &nodelen))
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1564
		return NULL;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1565
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1566
	if (nodelen < 4) {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1567
		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
  1568
		return NULL;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1569
	}
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1570
17353
bde1185f406c revlog: don't try to partialmatch strings those length > 40
sorcerer
parents: 17165
diff changeset
  1571
	if (nodelen > 40) {
bde1185f406c revlog: don't try to partialmatch strings those length > 40
sorcerer
parents: 17165
diff changeset
  1572
		PyErr_SetString(PyExc_ValueError, "key too long");
bde1185f406c revlog: don't try to partialmatch strings those length > 40
sorcerer
parents: 17165
diff changeset
  1573
		return NULL;
bde1185f406c revlog: don't try to partialmatch strings those length > 40
sorcerer
parents: 17165
diff changeset
  1574
	}
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1575
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1576
	for (i = 0; i < nodelen; i++)
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1577
		hexdigit(node, i);
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1578
	if (PyErr_Occurred()) {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1579
		/* input contains non-hex characters */
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1580
		PyErr_Clear();
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1581
		Py_RETURN_NONE;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1582
	}
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1583
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1584
	rev = nt_partialmatch(self, node, nodelen);
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1585
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1586
	switch (rev) {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1587
	case -4:
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1588
		raise_revlog_error();
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1589
	case -3:
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1590
		return NULL;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1591
	case -2:
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1592
		Py_RETURN_NONE;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1593
	case -1:
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1594
		return PyString_FromStringAndSize(nullid, 20);
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1595
	}
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1596
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1597
	fullnode = index_node(self, rev);
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1598
	if (fullnode == NULL) {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1599
		PyErr_Format(PyExc_IndexError,
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1600
			     "could not access rev %d", rev);
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1601
		return NULL;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1602
	}
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1603
	return PyString_FromStringAndSize(fullnode, 20);
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1604
}
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  1605
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1606
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
  1607
{
16679
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
  1608
	Py_ssize_t nodelen;
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
  1609
	PyObject *val;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1610
	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
  1611
	int rev;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1612
16679
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
  1613
	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
  1614
		return NULL;
16679
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
  1615
	if (node_check(val, &node, &nodelen) == -1)
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
  1616
		return NULL;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1617
	rev = index_find_node(self, node, nodelen);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1618
	if (rev ==  -3)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1619
		return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1620
	if (rev == -2)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1621
		Py_RETURN_NONE;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1622
	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
  1623
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1624
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1625
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
  1626
{
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1627
	char *node;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1628
	Py_ssize_t nodelen;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1629
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1630
	if (PyInt_Check(value)) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1631
		long rev = PyInt_AS_LONG(value);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1632
		return rev >= -1 && rev < index_length(self);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1633
	}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1634
16679
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
  1635
	if (node_check(value, &node, &nodelen) == -1)
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
  1636
		return -1;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1637
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1638
	switch (index_find_node(self, node, nodelen)) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1639
	case -3:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1640
		return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1641
	case -2:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1642
		return 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1643
	default:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1644
		return 1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1645
	}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1646
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  1647
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1648
typedef uint64_t bitmask;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1649
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1650
/*
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1651
 * 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
  1652
 * 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
  1653
 * "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
  1654
 */
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1655
static PyObject *find_gca_candidates(indexObject *self, const int *revs,
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1656
				     int revcount)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1657
{
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1658
	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
  1659
	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
  1660
	PyObject *gca = PyList_New(0);
20555
4add43865a9b ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents: 20554
diff changeset
  1661
	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
  1662
	int maxrev = -1;
22399
9f490afcb067 parsers: use bitmask type consistently in find_gca_candidates
Henrik Stuart <hg@hstuart.dk>
parents: 21871
diff changeset
  1663
	bitmask sp;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1664
	bitmask *seen;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1665
19727
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
  1666
	if (gca == NULL)
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
  1667
		return PyErr_NoMemory();
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
  1668
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1669
	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
  1670
		if (revs[i] > maxrev)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1671
			maxrev = revs[i];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1672
	}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1673
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1674
	seen = calloc(sizeof(*seen), maxrev + 1);
19727
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
  1675
	if (seen == NULL) {
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
  1676
		Py_DECREF(gca);
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1677
		return PyErr_NoMemory();
19727
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
  1678
	}
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1679
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1680
	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
  1681
		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
  1682
20555
4add43865a9b ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents: 20554
diff changeset
  1683
	interesting = revcount;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1684
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1685
	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
  1686
		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
  1687
		int parents[2];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1688
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1689
		if (!sv)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1690
			continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1691
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1692
		if (sv < poison) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1693
			interesting -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1694
			if (sv == allseen) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1695
				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
  1696
				if (obj == NULL)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1697
					goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1698
				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
  1699
					Py_DECREF(obj);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1700
					goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1701
				}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1702
				sv |= poison;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1703
				for (i = 0; i < revcount; i++) {
20555
4add43865a9b ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents: 20554
diff changeset
  1704
					if (revs[i] == v)
4add43865a9b ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents: 20554
diff changeset
  1705
						goto done;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1706
				}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1707
			}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1708
		}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1709
		index_get_parents(self, v, parents);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1710
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1711
		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
  1712
			int p = parents[i];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1713
			if (p == -1)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1714
				continue;
19030
48d6f436363e parsers: fix variable declaration position issue
Matt Mackall <mpm@selenic.com>
parents: 18988
diff changeset
  1715
			sp = seen[p];
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1716
			if (sv < poison) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1717
				if (sp == 0) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1718
					seen[p] = sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1719
					interesting++;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1720
				}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1721
				else if (sp != sv)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1722
					seen[p] |= sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1723
			} else {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1724
				if (sp && sp < poison)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1725
					interesting--;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1726
				seen[p] = sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1727
			}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1728
		}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1729
	}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1730
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1731
done:
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1732
	free(seen);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1733
	return gca;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1734
bail:
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1735
	free(seen);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1736
	Py_XDECREF(gca);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1737
	return NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1738
}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1739
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1740
/*
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1741
 * 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
  1742
 * path to the root.
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1743
 */
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1744
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
  1745
{
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1746
	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
  1747
	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
  1748
	int *depth, *interesting = NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1749
	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
  1750
	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
  1751
	long *seen = NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1752
	int maxrev = -1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1753
	long final;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1754
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1755
	if (revcount > capacity) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1756
		PyErr_Format(PyExc_OverflowError,
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1757
			     "bitset size (%ld) > capacity (%ld)",
19062
365b0de17c1c parsers: remove warning: format ‘%ld’ expects argument of type ‘long int’
André Sintzoff <andre.sintzoff@gmail.com>
parents: 19030
diff changeset
  1758
			     (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
  1759
		return NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1760
	}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1761
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1762
	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
  1763
		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
  1764
		if (n > maxrev)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1765
			maxrev = n;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1766
	}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1767
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1768
	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
  1769
	if (depth == NULL)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1770
		return PyErr_NoMemory();
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1771
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1772
	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
  1773
	if (seen == NULL) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1774
		PyErr_NoMemory();
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1775
		goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1776
	}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1777
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1778
	interesting = calloc(sizeof(*interesting), 2 << revcount);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1779
	if (interesting == NULL) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1780
		PyErr_NoMemory();
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1781
		goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1782
	}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1783
19502
8704477ad3b6 ancestor.deepest: sort revs in C version
Siddharth Agarwal <sid0@fb.com>
parents: 19062
diff changeset
  1784
	if (PyList_Sort(revs) == -1)
8704477ad3b6 ancestor.deepest: sort revs in C version
Siddharth Agarwal <sid0@fb.com>
parents: 19062
diff changeset
  1785
		goto bail;
8704477ad3b6 ancestor.deepest: sort revs in C version
Siddharth Agarwal <sid0@fb.com>
parents: 19062
diff changeset
  1786
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1787
	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
  1788
		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
  1789
		long b = 1l << i;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1790
		depth[n] = 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1791
		seen[n] = b;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1792
		interesting[b] = 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1793
	}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1794
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1795
	ninteresting = (int)revcount;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1796
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1797
	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
  1798
		int dv = depth[v];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1799
		int parents[2];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1800
		long sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1801
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1802
		if (dv == 0)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1803
			continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1804
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1805
		sv = seen[v];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1806
		index_get_parents(self, v, parents);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1807
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1808
		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
  1809
			int p = parents[i];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1810
			long nsp, sp;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1811
			int dp;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1812
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1813
			if (p == -1)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1814
				continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1815
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1816
			dp = depth[p];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1817
			nsp = sp = seen[p];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1818
			if (dp <= dv) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1819
				depth[p] = dv + 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1820
				if (sp != sv) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1821
					interesting[sv] += 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1822
					nsp = seen[p] = sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1823
					if (sp) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1824
						interesting[sp] -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1825
						if (interesting[sp] == 0)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1826
							ninteresting -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1827
					}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1828
				}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1829
			}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1830
			else if (dv == dp - 1) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1831
				nsp = sp | sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1832
				if (nsp == sp)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1833
					continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1834
				seen[p] = nsp;
19503
f2dfda6ac152 ancestor.deepest: decrement ninteresting correctly (issue3984)
Wei, Elson <elson.wei@gmail.com>
parents: 19502
diff changeset
  1835
				interesting[sp] -= 1;
f2dfda6ac152 ancestor.deepest: decrement ninteresting correctly (issue3984)
Wei, Elson <elson.wei@gmail.com>
parents: 19502
diff changeset
  1836
				if (interesting[sp] == 0 && interesting[nsp] > 0)
f2dfda6ac152 ancestor.deepest: decrement ninteresting correctly (issue3984)
Wei, Elson <elson.wei@gmail.com>
parents: 19502
diff changeset
  1837
					ninteresting -= 1;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1838
				interesting[nsp] += 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1839
			}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1840
		}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1841
		interesting[sv] -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1842
		if (interesting[sv] == 0)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1843
			ninteresting -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1844
	}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1845
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1846
	final = 0;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1847
	j = ninteresting;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1848
	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
  1849
		if (interesting[i] == 0)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1850
			continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1851
		final |= i;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1852
		j -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1853
	}
21730
8da100383dc3 parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents: 21103
diff changeset
  1854
	if (final == 0) {
8da100383dc3 parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents: 21103
diff changeset
  1855
		keys = PyList_New(0);
8da100383dc3 parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents: 21103
diff changeset
  1856
		goto bail;
8da100383dc3 parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents: 21103
diff changeset
  1857
	}
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1858
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1859
	dict = PyDict_New();
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1860
	if (dict == NULL)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1861
		goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1862
19504
2fa303619b4d ancestor.deepest: ignore ninteresting while building result (issue3984)
Siddharth Agarwal <sid0@fb.com>
parents: 19503
diff changeset
  1863
	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
  1864
		PyObject *key;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1865
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1866
		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
  1867
			continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1868
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1869
		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
  1870
		Py_INCREF(key);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1871
		Py_INCREF(Py_None);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1872
		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
  1873
			Py_DECREF(key);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1874
			Py_DECREF(Py_None);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1875
			goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1876
		}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1877
	}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1878
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1879
	keys = PyDict_Keys(dict);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1880
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1881
bail:
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1882
	free(depth);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1883
	free(seen);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1884
	free(interesting);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1885
	Py_XDECREF(dict);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1886
21730
8da100383dc3 parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents: 21103
diff changeset
  1887
	return keys;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1888
}
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1889
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  1890
/*
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1891
 * Given a (possibly overlapping) set of revs, return all the
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1892
 * common ancestors heads: heads(::args[0] and ::a[1] and ...)
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1893
 */
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1894
static PyObject *index_commonancestorsheads(indexObject *self, PyObject *args)
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1895
{
21103
628c16489d1c parsers: remove unnecessary gca variable in index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 21102
diff changeset
  1896
	PyObject *ret = NULL;
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1897
	Py_ssize_t argcount, i, len;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1898
	bitmask repeat = 0;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1899
	int revcount = 0;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1900
	int *revs;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1901
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1902
	argcount = PySequence_Length(args);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1903
	revs = malloc(argcount * sizeof(*revs));
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1904
	if (argcount > 0 && revs == NULL)
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1905
		return PyErr_NoMemory();
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1906
	len = index_length(self) - 1;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1907
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1908
	for (i = 0; i < argcount; i++) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1909
		static const int capacity = 24;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1910
		PyObject *obj = PySequence_GetItem(args, i);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1911
		bitmask x;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1912
		long val;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1913
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1914
		if (!PyInt_Check(obj)) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1915
			PyErr_SetString(PyExc_TypeError,
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1916
					"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
  1917
			Py_DECREF(obj);
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1918
			goto bail;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1919
		}
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1920
		val = PyInt_AsLong(obj);
23945
33d6aaf84c9e parsers.c: fix a memory leak in index_commonancestorsheads
Augie Fackler <augie@google.com>
parents: 23944
diff changeset
  1921
		Py_DECREF(obj);
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1922
		if (val == -1) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1923
			ret = PyList_New(0);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1924
			goto done;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1925
		}
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1926
		if (val < 0 || val >= len) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1927
			PyErr_SetString(PyExc_IndexError,
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1928
					"index out of range");
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1929
			goto bail;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1930
		}
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1931
		/* this cheesy bloom filter lets us avoid some more
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1932
		 * expensive duplicate checks in the common set-is-disjoint
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1933
		 * case */
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1934
		x = 1ull << (val & 0x3f);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1935
		if (repeat & x) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1936
			int k;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1937
			for (k = 0; k < revcount; k++) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1938
				if (val == revs[k])
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1939
					goto duplicate;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1940
			}
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1941
		}
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1942
		else repeat |= x;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1943
		if (revcount >= capacity) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1944
			PyErr_Format(PyExc_OverflowError,
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1945
				     "bitset size (%d) > capacity (%d)",
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1946
				     revcount, capacity);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1947
			goto bail;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1948
		}
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1949
		revs[revcount++] = (int)val;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1950
	duplicate:;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1951
	}
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1952
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1953
	if (revcount == 0) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1954
		ret = PyList_New(0);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1955
		goto done;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1956
	}
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1957
	if (revcount == 1) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1958
		PyObject *obj;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1959
		ret = PyList_New(1);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1960
		if (ret == NULL)
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1961
			goto bail;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1962
		obj = PyInt_FromLong(revs[0]);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1963
		if (obj == NULL)
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1964
			goto bail;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1965
		PyList_SET_ITEM(ret, 0, obj);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1966
		goto done;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1967
	}
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1968
21103
628c16489d1c parsers: remove unnecessary gca variable in index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 21102
diff changeset
  1969
	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
  1970
	if (ret == NULL)
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1971
		goto bail;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1972
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1973
done:
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1974
	free(revs);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1975
	return ret;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1976
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1977
bail:
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1978
	free(revs);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1979
	Py_XDECREF(ret);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1980
	return NULL;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1981
}
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1982
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  1983
/*
24004
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  1984
 * 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
  1985
 * 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
  1986
 */
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  1987
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
  1988
{
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  1989
	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
  1990
	if (gca == NULL)
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  1991
		return NULL;
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  1992
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  1993
	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
  1994
		Py_INCREF(gca);
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  1995
		return gca;
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  1996
	}
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  1997
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  1998
	return find_deepest(self, gca);
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  1999
}
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  2000
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
  2001
/*
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2002
 * 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
  2003
 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2004
static void nt_invalidate_added(indexObject *self, Py_ssize_t start)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2005
{
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2006
	Py_ssize_t i, len = PyList_GET_SIZE(self->added);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2007
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2008
	for (i = start; i < len; i++) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2009
		PyObject *tuple = PyList_GET_ITEM(self->added, i);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2010
		PyObject *node = PyTuple_GET_ITEM(tuple, 7);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2011
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2012
		nt_insert(self, PyString_AS_STRING(node), -1);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2013
	}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2014
16732
277e2acb7e5c parsers: use Py_CLEAR where appropriate
Bryan O'Sullivan <bryano@fb.com>
parents: 16699
diff changeset
  2015
	if (start == 0)
277e2acb7e5c parsers: use Py_CLEAR where appropriate
Bryan O'Sullivan <bryano@fb.com>
parents: 16699
diff changeset
  2016
		Py_CLEAR(self->added);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2017
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2018
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2019
/*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2020
 * Delete a numeric range of revs, which must be at the end of the
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2021
 * range, but exclude the sentinel nullid entry.
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2022
 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2023
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
  2024
{
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2025
	Py_ssize_t start, stop, step, slicelength;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2026
	Py_ssize_t length = index_length(self);
16784
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
  2027
	int ret = 0;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2028
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2029
	if (PySlice_GetIndicesEx((PySliceObject*)item, length,
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2030
				 &start, &stop, &step, &slicelength) < 0)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2031
		return -1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2032
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2033
	if (slicelength <= 0)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2034
		return 0;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2035
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2036
	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
  2037
		stop = start;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2038
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2039
	if (step < 0) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2040
		stop = start + 1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2041
		start = stop + step*(slicelength - 1) - 1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2042
		step = -step;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2043
	}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2044
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2045
	if (step != 1) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2046
		PyErr_SetString(PyExc_ValueError,
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2047
				"revlog index delete requires step size of 1");
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2048
		return -1;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2049
	}
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2050
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2051
	if (stop != length - 1) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2052
		PyErr_SetString(PyExc_IndexError,
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2053
				"revlog index deletion indices are invalid");
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2054
		return -1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2055
	}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2056
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2057
	if (start < self->length - 1) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2058
		if (self->nt) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2059
			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
  2060
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2061
			for (i = start + 1; i < self->length - 1; i++) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2062
				const char *node = index_node(self, i);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2063
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2064
				if (node)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2065
					nt_insert(self, node, -1);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2066
			}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2067
			if (self->added)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2068
				nt_invalidate_added(self, 0);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2069
			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
  2070
				self->ntrev = (int)start;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2071
		}
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2072
		self->length = start + 1;
18504
d1d5fdcc2d46 parsers: fix memleak of revlog cache entries on strip
Yuya Nishihara <yuya@tcha.org>
parents: 18430
diff changeset
  2073
		if (start < self->raw_length) {
d1d5fdcc2d46 parsers: fix memleak of revlog cache entries on strip
Yuya Nishihara <yuya@tcha.org>
parents: 18430
diff changeset
  2074
			if (self->cache) {
d1d5fdcc2d46 parsers: fix memleak of revlog cache entries on strip
Yuya Nishihara <yuya@tcha.org>
parents: 18430
diff changeset
  2075
				Py_ssize_t i;
d1d5fdcc2d46 parsers: fix memleak of revlog cache entries on strip
Yuya Nishihara <yuya@tcha.org>
parents: 18430
diff changeset
  2076
				for (i = start; i < self->raw_length; i++)
d1d5fdcc2d46 parsers: fix memleak of revlog cache entries on strip
Yuya Nishihara <yuya@tcha.org>
parents: 18430
diff changeset
  2077
					Py_CLEAR(self->cache[i]);
d1d5fdcc2d46 parsers: fix memleak of revlog cache entries on strip
Yuya Nishihara <yuya@tcha.org>
parents: 18430
diff changeset
  2078
			}
16784
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
  2079
			self->raw_length = start;
18504
d1d5fdcc2d46 parsers: fix memleak of revlog cache entries on strip
Yuya Nishihara <yuya@tcha.org>
parents: 18430
diff changeset
  2080
		}
16784
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
  2081
		goto done;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2082
	}
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2083
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2084
	if (self->nt) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2085
		nt_invalidate_added(self, start - self->length + 1);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2086
		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
  2087
			self->ntrev = (int)start;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2088
	}
16784
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
  2089
	if (self->added)
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
  2090
		ret = PyList_SetSlice(self->added, start - self->length + 1,
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
  2091
				      PyList_GET_SIZE(self->added), NULL);
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
  2092
done:
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
  2093
	Py_CLEAR(self->headrevs);
16784
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
  2094
	return ret;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2095
}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2096
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2097
/*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2098
 * Supported ops:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2099
 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2100
 * slice deletion
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2101
 * 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
  2102
 * 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
  2103
 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2104
static int index_assign_subscript(indexObject *self, PyObject *item,
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2105
				  PyObject *value)
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
	char *node;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2108
	Py_ssize_t nodelen;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2109
	long rev;
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 (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
  2112
		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
  2113
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2114
	if (node_check(item, &node, &nodelen) == -1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2115
		return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2116
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2117
	if (value == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2118
		return self->nt ? nt_insert(self, node, -1) : 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2119
	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
  2120
	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
  2121
		if (!PyErr_Occurred())
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2122
			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
  2123
		return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2124
	}
23468
ee311681e591 parsers: ensure revlog index node tree is initialized before insertion
Mike Edgar <adgar@google.com>
parents: 23087
diff changeset
  2125
ee311681e591 parsers: ensure revlog index node tree is initialized before insertion
Mike Edgar <adgar@google.com>
parents: 23087
diff changeset
  2126
	if (nt_init(self) == -1)
ee311681e591 parsers: ensure revlog index node tree is initialized before insertion
Mike Edgar <adgar@google.com>
parents: 23087
diff changeset
  2127
		return -1;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2128
	return nt_insert(self, node, (int)rev);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  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
/*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2132
 * 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
  2133
 * 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
  2134
 */
22401
9ba8a93e55f5 parsers: ensure correct return type for inline_scan
Henrik Stuart <hg@hstuart.dk>
parents: 22400
diff changeset
  2135
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
  2136
{
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2137
	const char *data = PyString_AS_STRING(self->data);
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
  2138
	Py_ssize_t pos = 0;
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
  2139
	Py_ssize_t end = PyString_GET_SIZE(self->data);
16863
bbedef66c6f3 parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents: 16787
diff changeset
  2140
	long incr = v1_hdrsize;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2141
	Py_ssize_t len = 0;
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
  2142
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
  2143
	while (pos + v1_hdrsize <= end && pos >= 0) {
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2144
		uint32_t comp_len;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2145
		/* 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
  2146
		comp_len = getbe32(data + pos + 8);
16863
bbedef66c6f3 parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents: 16787
diff changeset
  2147
		incr = v1_hdrsize + comp_len;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2148
		if (offsets)
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
  2149
			offsets[len] = data + pos;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2150
		len++;
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
  2151
		pos += incr;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2152
	}
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
  2153
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
  2154
	if (pos != end) {
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2155
		if (!PyErr_Occurred())
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2156
			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
  2157
		return -1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2158
	}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2159
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2160
	return len;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2161
}
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
  2162
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2163
static int index_init(indexObject *self, PyObject *args)
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2164
{
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2165
	PyObject *data_obj, *inlined_obj;
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2166
	Py_ssize_t size;
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2167
20109
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
  2168
	/* Initialize before argument-checking to avoid index_dealloc() crash. */
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
  2169
	self->raw_length = 0;
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
  2170
	self->added = NULL;
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
  2171
	self->cache = NULL;
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
  2172
	self->data = NULL;
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
  2173
	self->headrevs = NULL;
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  2174
	self->filteredrevs = Py_None;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  2175
	Py_INCREF(Py_None);
20109
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
  2176
	self->nt = NULL;
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
  2177
	self->offsets = NULL;
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
  2178
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2179
	if (!PyArg_ParseTuple(args, "OO", &data_obj, &inlined_obj))
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2180
		return -1;
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2181
	if (!PyString_Check(data_obj)) {
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2182
		PyErr_SetString(PyExc_TypeError, "data is not a string");
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2183
		return -1;
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2184
	}
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2185
	size = PyString_GET_SIZE(data_obj);
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2186
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2187
	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
  2188
	self->data = data_obj;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2189
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2190
	self->ntlength = self->ntcapacity = 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2191
	self->ntdepth = self->ntsplits = 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2192
	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
  2193
	self->ntrev = -1;
16597
b767382a8675 parsers: fix refcount bug on corrupt index
Matt Mackall <mpm@selenic.com>
parents: 16572
diff changeset
  2194
	Py_INCREF(self->data);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2195
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2196
	if (self->inlined) {
22401
9ba8a93e55f5 parsers: ensure correct return type for inline_scan
Henrik Stuart <hg@hstuart.dk>
parents: 22400
diff changeset
  2197
		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
  2198
		if (len == -1)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2199
			goto bail;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2200
		self->raw_length = len;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2201
		self->length = len + 1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2202
	} else {
16863
bbedef66c6f3 parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents: 16787
diff changeset
  2203
		if (size % v1_hdrsize) {
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2204
			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
  2205
			goto bail;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2206
		}
16863
bbedef66c6f3 parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents: 16787
diff changeset
  2207
		self->raw_length = size / v1_hdrsize;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2208
		self->length = self->raw_length + 1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2209
	}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2210
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2211
	return 0;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2212
bail:
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2213
	return -1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2214
}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2215
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2216
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
  2217
{
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2218
	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
  2219
	return (PyObject *)self;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2220
}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2221
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2222
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
  2223
{
16370
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
  2224
	_index_clearcaches(self);
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  2225
	Py_XDECREF(self->filteredrevs);
20109
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
  2226
	Py_XDECREF(self->data);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2227
	Py_XDECREF(self->added);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2228
	PyObject_Del(self);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2229
}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2230
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2231
static PySequenceMethods index_sequence_methods = {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2232
	(lenfunc)index_length,   /* sq_length */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2233
	0,                       /* sq_concat */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2234
	0,                       /* sq_repeat */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2235
	(ssizeargfunc)index_get, /* sq_item */
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2236
	0,                       /* sq_slice */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2237
	0,                       /* sq_ass_item */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2238
	0,                       /* sq_ass_slice */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2239
	(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
  2240
};
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2241
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2242
static PyMappingMethods index_mapping_methods = {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2243
	(lenfunc)index_length,                 /* mp_length */
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2244
	(binaryfunc)index_getitem,             /* mp_subscript */
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2245
	(objobjargproc)index_assign_subscript, /* mp_ass_subscript */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2246
};
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2247
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2248
static PyMethodDef index_methods[] = {
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2249
	{"ancestors", (PyCFunction)index_ancestors, METH_VARARGS,
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
  2250
	 "return the gca set of the given revs"},
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2251
	{"commonancestorsheads", (PyCFunction)index_commonancestorsheads,
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2252
	  METH_VARARGS,
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
  2253
	  "return the heads of the common ancestors of the given revs"},
16370
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
  2254
	{"clearcaches", (PyCFunction)index_clearcaches, METH_NOARGS,
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
  2255
	 "clear the index caches"},
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2256
	{"get", (PyCFunction)index_m_get, METH_VARARGS,
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2257
	 "get an index entry"},
25190
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  2258
	{"computephasesmapsets", (PyCFunction)compute_phases_map_sets,
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
  2259
			METH_VARARGS, "compute phases"},
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
  2260
	{"headrevs", (PyCFunction)index_headrevs, METH_VARARGS,
23087
42342f9afe01 parsers: introduce headrevsfiltered in C extension
Mads Kiilerich <madski@unity3d.com>
parents: 23073
diff changeset
  2261
	 "get head revisions"}, /* Can do filtering since 3.2 */
42342f9afe01 parsers: introduce headrevsfiltered in C extension
Mads Kiilerich <madski@unity3d.com>
parents: 23073
diff changeset
  2262
	{"headrevsfiltered", (PyCFunction)index_headrevs, METH_VARARGS,
42342f9afe01 parsers: introduce headrevsfiltered in C extension
Mads Kiilerich <madski@unity3d.com>
parents: 23073
diff changeset
  2263
	 "get filtered head revisions"}, /* Can always do filtering */
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2264
	{"insert", (PyCFunction)index_insert, METH_VARARGS,
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2265
	 "insert an index entry"},
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2266
	{"partialmatch", (PyCFunction)index_partialmatch, METH_VARARGS,
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
  2267
	 "match a potentially ambiguous node ID"},
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2268
	{"stats", (PyCFunction)index_stats, METH_NOARGS,
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2269
	 "stats for the index"},
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2270
	{NULL} /* Sentinel */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2271
};
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2272
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2273
static PyGetSetDef index_getset[] = {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2274
	{"nodemap", (getter)index_nodemap, NULL, "nodemap", NULL},
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2275
	{NULL} /* Sentinel */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2276
};
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2277
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2278
static PyTypeObject indexType = {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2279
	PyObject_HEAD_INIT(NULL)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2280
	0,                         /* ob_size */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2281
	"parsers.index",           /* tp_name */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2282
	sizeof(indexObject),       /* tp_basicsize */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2283
	0,                         /* tp_itemsize */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2284
	(destructor)index_dealloc, /* tp_dealloc */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2285
	0,                         /* tp_print */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2286
	0,                         /* tp_getattr */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2287
	0,                         /* tp_setattr */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2288
	0,                         /* tp_compare */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2289
	0,                         /* tp_repr */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2290
	0,                         /* tp_as_number */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2291
	&index_sequence_methods,   /* tp_as_sequence */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2292
	&index_mapping_methods,    /* tp_as_mapping */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2293
	0,                         /* tp_hash */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2294
	0,                         /* tp_call */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2295
	0,                         /* tp_str */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2296
	0,                         /* tp_getattro */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2297
	0,                         /* tp_setattro */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2298
	0,                         /* tp_as_buffer */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2299
	Py_TPFLAGS_DEFAULT,        /* tp_flags */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2300
	"revlog index",            /* tp_doc */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2301
	0,                         /* tp_traverse */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2302
	0,                         /* tp_clear */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2303
	0,                         /* tp_richcompare */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2304
	0,                         /* tp_weaklistoffset */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2305
	0,                         /* tp_iter */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2306
	0,                         /* tp_iternext */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2307
	index_methods,             /* tp_methods */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2308
	0,                         /* tp_members */
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2309
	index_getset,              /* tp_getset */
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2310
	0,                         /* tp_base */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2311
	0,                         /* tp_dict */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2312
	0,                         /* tp_descr_get */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2313
	0,                         /* tp_descr_set */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2314
	0,                         /* tp_dictoffset */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2315
	(initproc)index_init,      /* tp_init */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2316
	0,                         /* tp_alloc */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2317
};
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2318
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2319
/*
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2320
 * returns a tuple of the form (index, index, cache) with elements as
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2321
 * follows:
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2322
 *
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
  2323
 * index: an index object that lazily parses RevlogNG records
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2324
 * cache: if data is inlined, a tuple (index_file_content, 0), else None
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2325
 *
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2326
 * added complications are for backwards compatibility
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2327
 */
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
  2328
static PyObject *parse_index2(PyObject *self, PyObject *args)
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2329
{
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2330
	PyObject *tuple = NULL, *cache = NULL;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2331
	indexObject *idx;
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2332
	int ret;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2333
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2334
	idx = PyObject_New(indexObject, &indexType);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2335
	if (idx == NULL)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2336
		goto bail;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2337
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2338
	ret = index_init(idx, args);
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
  2339
	if (ret == -1)
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2340
		goto bail;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2341
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2342
	if (idx->inlined) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2343
		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
  2344
		if (cache == NULL)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2345
			goto bail;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2346
	} else {
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2347
		cache = Py_None;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2348
		Py_INCREF(cache);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2349
	}
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2350
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2351
	tuple = Py_BuildValue("NN", idx, cache);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2352
	if (!tuple)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2353
		goto bail;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2354
	return tuple;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2355
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2356
bail:
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2357
	Py_XDECREF(idx);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2358
	Py_XDECREF(cache);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2359
	Py_XDECREF(tuple);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2360
	return NULL;
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2361
}
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
  2362
24017
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2363
#define BUMPED_FIX 1
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2364
#define USING_SHA_256 2
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2365
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2366
static PyObject *readshas(
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2367
	const char *source, unsigned char num, Py_ssize_t hashwidth)
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2368
{
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2369
	int i;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2370
	PyObject *list = PyTuple_New(num);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2371
	if (list == NULL) {
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2372
		return NULL;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2373
	}
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2374
	for (i = 0; i < num; i++) {
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2375
		PyObject *hash = PyString_FromStringAndSize(source, hashwidth);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2376
		if (hash == NULL) {
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2377
			Py_DECREF(list);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2378
			return NULL;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2379
		}
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2380
		PyTuple_SetItem(list, i, hash);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2381
		source += hashwidth;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2382
	}
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2383
	return list;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2384
}
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2385
24019
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2386
static PyObject *fm1readmarker(const char *data, uint32_t *msize)
24017
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2387
{
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2388
	const char *meta;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2389
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2390
	double mtime;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2391
	int16_t tz;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2392
	uint16_t flags;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2393
	unsigned char nsuccs, nparents, nmetadata;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2394
	Py_ssize_t hashwidth = 20;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2395
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2396
	PyObject *prec = NULL, *parents = NULL, *succs = NULL;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2397
	PyObject *metadata = NULL, *ret = NULL;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2398
	int i;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2399
24019
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2400
	*msize = getbe32(data);
24017
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2401
	data += 4;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2402
	mtime = getbefloat64(data);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2403
	data += 8;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2404
	tz = getbeint16(data);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2405
	data += 2;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2406
	flags = getbeuint16(data);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2407
	data += 2;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2408
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2409
	if (flags & USING_SHA_256) {
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2410
		hashwidth = 32;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2411
	}
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2412
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2413
	nsuccs = (unsigned char)(*data++);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2414
	nparents = (unsigned char)(*data++);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2415
	nmetadata = (unsigned char)(*data++);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2416
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2417
	prec = PyString_FromStringAndSize(data, hashwidth);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2418
	data += hashwidth;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2419
	if (prec == NULL) {
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2420
		goto bail;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2421
	}
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2422
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2423
	succs = readshas(data, nsuccs, hashwidth);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2424
	if (succs == NULL) {
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2425
		goto bail;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2426
	}
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2427
	data += nsuccs * hashwidth;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2428
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2429
	if (nparents == 1 || nparents == 2) {
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2430
		parents = readshas(data, nparents, hashwidth);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2431
		if (parents == NULL) {
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2432
			goto bail;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2433
		}
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2434
		data += nparents * hashwidth;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2435
	} else {
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2436
		parents = Py_None;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2437
	}
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2438
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2439
	meta = data + (2 * nmetadata);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2440
	metadata = PyTuple_New(nmetadata);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2441
	if (metadata == NULL) {
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2442
		goto bail;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2443
	}
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2444
	for (i = 0; i < nmetadata; i++) {
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2445
		PyObject *tmp, *left = NULL, *right = NULL;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2446
		Py_ssize_t metasize = (unsigned char)(*data++);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2447
		left = PyString_FromStringAndSize(meta, metasize);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2448
		meta += metasize;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2449
		metasize = (unsigned char)(*data++);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2450
		right = PyString_FromStringAndSize(meta, metasize);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2451
		meta += metasize;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2452
		if (!left || !right) {
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2453
			Py_XDECREF(left);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2454
			Py_XDECREF(right);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2455
			goto bail;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2456
		}
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2457
		tmp = PyTuple_Pack(2, left, right);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2458
		Py_DECREF(left);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2459
		Py_DECREF(right);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2460
		if (!tmp) {
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2461
			goto bail;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2462
		}
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2463
		PyTuple_SetItem(metadata, i, tmp);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2464
	}
24019
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2465
	ret = Py_BuildValue("(OOHO(di)O)", prec, succs, flags,
24017
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2466
			    metadata, mtime, (int)tz * 60, parents);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2467
bail:
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2468
	Py_XDECREF(prec);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2469
	Py_XDECREF(succs);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2470
	Py_XDECREF(metadata);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2471
	if (parents != Py_None)
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2472
		Py_XDECREF(parents);
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2473
	return ret;
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2474
}
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
  2475
24019
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2476
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2477
static PyObject *fm1readmarkers(PyObject *self, PyObject *args) {
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2478
	const char *data;
24032
c53bc2e52514 parsers: use k instead of n for PyArg_ParseTuple because python 2.4 is awful
Augie Fackler <augie@google.com>
parents: 24019
diff changeset
  2479
	Py_ssize_t datalen;
c53bc2e52514 parsers: use k instead of n for PyArg_ParseTuple because python 2.4 is awful
Augie Fackler <augie@google.com>
parents: 24019
diff changeset
  2480
	/* only unsigned long because python 2.4, should be Py_ssize_t */
c53bc2e52514 parsers: use k instead of n for PyArg_ParseTuple because python 2.4 is awful
Augie Fackler <augie@google.com>
parents: 24019
diff changeset
  2481
	unsigned long offset, stop;
24019
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2482
	PyObject *markers = NULL;
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2483
24032
c53bc2e52514 parsers: use k instead of n for PyArg_ParseTuple because python 2.4 is awful
Augie Fackler <augie@google.com>
parents: 24019
diff changeset
  2484
	/* replace kk with nn when we drop Python 2.4 */
c53bc2e52514 parsers: use k instead of n for PyArg_ParseTuple because python 2.4 is awful
Augie Fackler <augie@google.com>
parents: 24019
diff changeset
  2485
	if (!PyArg_ParseTuple(args, "s#kk", &data, &datalen, &offset, &stop)) {
24019
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2486
		return NULL;
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2487
	}
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2488
	data += offset;
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2489
	markers = PyList_New(0);
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2490
	if (!markers) {
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2491
		return NULL;
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2492
	}
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2493
	while (offset < stop) {
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2494
		uint32_t msize;
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2495
		int error;
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2496
		PyObject *record = fm1readmarker(data, &msize);
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2497
		if (!record) {
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2498
			goto bail;
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2499
		}
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2500
		error = PyList_Append(markers, record);
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2501
		Py_DECREF(record);
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2502
		if (error) {
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2503
			goto bail;
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2504
		}
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2505
		data += msize;
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2506
		offset += msize;
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2507
	}
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2508
	return markers;
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2509
bail:
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2510
	Py_DECREF(markers);
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2511
	return NULL;
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2512
}
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2513
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
  2514
static char parsers_doc[] = "Efficient content parsing.";
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
  2515
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents: 17356
diff changeset
  2516
PyObject *encodedir(PyObject *self, PyObject *args);
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
  2517
PyObject *pathencode(PyObject *self, PyObject *args);
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17616
diff changeset
  2518
PyObject *lowerencode(PyObject *self, PyObject *args);
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents: 17356
diff changeset
  2519
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
  2520
static PyMethodDef methods[] = {
16955
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
  2521
	{"pack_dirstate", pack_dirstate, METH_VARARGS, "pack a dirstate\n"},
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
  2522
	{"parse_manifest", parse_manifest, METH_VARARGS, "parse a manifest\n"},
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
  2523
	{"parse_dirstate", parse_dirstate, METH_VARARGS, "parse a dirstate\n"},
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
  2524
	{"parse_index2", parse_index2, METH_VARARGS, "parse a revlog index\n"},
22778
80f2b63dd83a parsers: add a function to efficiently lowercase ASCII strings
Siddharth Agarwal <sid0@fb.com>
parents: 22604
diff changeset
  2525
	{"asciilower", asciilower, METH_VARARGS, "lowercase an ASCII string\n"},
24577
bf55df007535 parsers: introduce an asciiupper function
Siddharth Agarwal <sid0@fb.com>
parents: 24576
diff changeset
  2526
	{"asciiupper", asciiupper, METH_VARARGS, "uppercase an ASCII string\n"},
24609
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
  2527
	{"make_file_foldmap", make_file_foldmap, METH_VARARGS,
670aaee7931c parsers: add a C function to create a file foldmap
Siddharth Agarwal <sid0@fb.com>
parents: 24606
diff changeset
  2528
	 "make file foldmap\n"},
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents: 17356
diff changeset
  2529
	{"encodedir", encodedir, METH_VARARGS, "encodedir a path\n"},
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
  2530
	{"pathencode", pathencode, METH_VARARGS, "fncache-encode a path\n"},
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17616
diff changeset
  2531
	{"lowerencode", lowerencode, METH_VARARGS, "lower-encode a path\n"},
24019
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2532
	{"fm1readmarkers", fm1readmarkers, METH_VARARGS,
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24017
diff changeset
  2533
			"parse v1 obsolete markers\n"},
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
  2534
	{NULL, NULL}
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
  2535
};
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
  2536
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents: 18567
diff changeset
  2537
void dirs_module_init(PyObject *mod);
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents: 24032
diff changeset
  2538
void manifest_module_init(PyObject *mod);
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents: 18567
diff changeset
  2539
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2540
static void module_init(PyObject *mod)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2541
{
20742
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2542
	/* This module constant has two purposes.  First, it lets us unit test
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2543
	 * the ImportError raised without hard-coding any error text.  This
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2544
	 * means we can change the text in the future without breaking tests,
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2545
	 * even across changesets without a recompile.  Second, its presence
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2546
	 * can be used to determine whether the version-checking logic is
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2547
	 * present, which also helps in testing across changesets without a
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2548
	 * recompile.  Note that this means the pure-Python version of parsers
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2549
	 * should not have this module constant. */
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2550
	PyModule_AddStringConstant(mod, "versionerrortext", versionerrortext);
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2551
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents: 18567
diff changeset
  2552
	dirs_module_init(mod);
24214
a5f1bccd2996 manifest.c: new extension code to lazily parse manifests
Augie Fackler <augie@google.com>
parents: 24032
diff changeset
  2553
	manifest_module_init(mod);
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents: 18567
diff changeset
  2554
16604
48e42f984074 parsers: statically initializing tp_new to PyType_GenericNew is not portable
Adrian Buehlmann <adrian@cadifra.com>
parents: 16597
diff changeset
  2555
	indexType.tp_new = PyType_GenericNew;
21809
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
  2556
	if (PyType_Ready(&indexType) < 0 ||
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
  2557
	    PyType_Ready(&dirstateTupleType) < 0)
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2558
		return;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2559
	Py_INCREF(&indexType);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2560
	PyModule_AddObject(mod, "index", (PyObject *)&indexType);
21809
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
  2561
	Py_INCREF(&dirstateTupleType);
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
  2562
	PyModule_AddObject(mod, "dirstatetuple",
e250b8300e6e parsers: inline fields of dirstate values in C version
Siddharth Agarwal <sid0@fb.com>
parents: 21807
diff changeset
  2563
			   (PyObject *)&dirstateTupleType);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2564
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2565
	nullentry = Py_BuildValue("iiiiiiis#", 0, 0, 0,
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2566
				  -1, -1, -1, -1, nullid, 20);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2567
	if (nullentry)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2568
		PyObject_GC_UnTrack(nullentry);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2569
}
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2570
20742
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2571
static int check_python_version(void)
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2572
{
23943
5fb44983a696 parsers: don't leak references to sys et al in check_python_version
Augie Fackler <augie@google.com>
parents: 23942
diff changeset
  2573
	PyObject *sys = PyImport_ImportModule("sys"), *ver;
5fb44983a696 parsers: don't leak references to sys et al in check_python_version
Augie Fackler <augie@google.com>
parents: 23942
diff changeset
  2574
	long hexversion;
5fb44983a696 parsers: don't leak references to sys et al in check_python_version
Augie Fackler <augie@google.com>
parents: 23942
diff changeset
  2575
	if (!sys)
5fb44983a696 parsers: don't leak references to sys et al in check_python_version
Augie Fackler <augie@google.com>
parents: 23942
diff changeset
  2576
		return -1;
5fb44983a696 parsers: don't leak references to sys et al in check_python_version
Augie Fackler <augie@google.com>
parents: 23942
diff changeset
  2577
	ver = PyObject_GetAttrString(sys, "hexversion");
5fb44983a696 parsers: don't leak references to sys et al in check_python_version
Augie Fackler <augie@google.com>
parents: 23942
diff changeset
  2578
	Py_DECREF(sys);
5fb44983a696 parsers: don't leak references to sys et al in check_python_version
Augie Fackler <augie@google.com>
parents: 23942
diff changeset
  2579
	if (!ver)
5fb44983a696 parsers: don't leak references to sys et al in check_python_version
Augie Fackler <augie@google.com>
parents: 23942
diff changeset
  2580
		return -1;
5fb44983a696 parsers: don't leak references to sys et al in check_python_version
Augie Fackler <augie@google.com>
parents: 23942
diff changeset
  2581
	hexversion = PyInt_AsLong(ver);
5fb44983a696 parsers: don't leak references to sys et al in check_python_version
Augie Fackler <augie@google.com>
parents: 23942
diff changeset
  2582
	Py_DECREF(ver);
20742
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2583
	/* sys.hexversion is a 32-bit number by default, so the -1 case
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2584
	 * should only occur in unusual circumstances (e.g. if sys.hexversion
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2585
	 * is manually set to an invalid value). */
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2586
	if ((hexversion == -1) || (hexversion >> 16 != PY_VERSION_HEX >> 16)) {
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2587
		PyErr_Format(PyExc_ImportError, "%s: The Mercurial extension "
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2588
			"modules were compiled with Python " PY_VERSION ", but "
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2589
			"Mercurial is currently using Python with sys.hexversion=%ld: "
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2590
			"Python %s\n at: %s", versionerrortext, hexversion,
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2591
			Py_GetVersion(), Py_GetProgramFullPath());
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2592
		return -1;
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2593
	}
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2594
	return 0;
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2595
}
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2596
11361
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
  2597
#ifdef IS_PY3K
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
  2598
static struct PyModuleDef parsers_module = {
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
  2599
	PyModuleDef_HEAD_INIT,
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
  2600
	"parsers",
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
  2601
	parsers_doc,
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
  2602
	-1,
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
  2603
	methods
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
  2604
};
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
  2605
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
  2606
PyMODINIT_FUNC PyInit_parsers(void)
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
  2607
{
20797
e286ab22e461 parsers: fix compiler errors on MSVC 2008
Matt Harbison <matt_harbison@yahoo.com>
parents: 20742
diff changeset
  2608
	PyObject *mod;
e286ab22e461 parsers: fix compiler errors on MSVC 2008
Matt Harbison <matt_harbison@yahoo.com>
parents: 20742
diff changeset
  2609
20742
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2610
	if (check_python_version() == -1)
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2611
		return;
20797
e286ab22e461 parsers: fix compiler errors on MSVC 2008
Matt Harbison <matt_harbison@yahoo.com>
parents: 20742
diff changeset
  2612
	mod = PyModule_Create(&parsers_module);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2613
	module_init(mod);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2614
	return mod;
11361
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
  2615
}
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
  2616
#else
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
  2617
PyMODINIT_FUNC initparsers(void)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
  2618
{
20797
e286ab22e461 parsers: fix compiler errors on MSVC 2008
Matt Harbison <matt_harbison@yahoo.com>
parents: 20742
diff changeset
  2619
	PyObject *mod;
e286ab22e461 parsers: fix compiler errors on MSVC 2008
Matt Harbison <matt_harbison@yahoo.com>
parents: 20742
diff changeset
  2620
20742
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2621
	if (check_python_version() == -1)
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
  2622
		return;
20797
e286ab22e461 parsers: fix compiler errors on MSVC 2008
Matt Harbison <matt_harbison@yahoo.com>
parents: 20742
diff changeset
  2623
	mod = Py_InitModule3("parsers", methods, parsers_doc);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
  2624
	module_init(mod);
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
  2625
}
11361
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
  2626
#endif