2010-06-16 02:49:56 +04:00
|
|
|
/*
|
|
|
|
util.h - utility functions for interfacing with the various python APIs.
|
|
|
|
|
|
|
|
This software may be used and distributed according to the terms of
|
|
|
|
the GNU General Public License, incorporated herein by reference.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _HG_UTIL_H_
|
|
|
|
#define _HG_UTIL_H_
|
|
|
|
|
2016-06-06 14:08:13 +03:00
|
|
|
#include "compat.h"
|
|
|
|
|
2010-06-16 02:49:56 +04:00
|
|
|
#if PY_MAJOR_VERSION >= 3
|
|
|
|
|
|
|
|
#define IS_PY3K
|
|
|
|
#define PyInt_FromLong PyLong_FromLong
|
2010-07-02 23:21:38 +04:00
|
|
|
#define PyInt_AsLong PyLong_AsLong
|
2010-06-16 02:49:56 +04:00
|
|
|
|
2010-07-02 23:21:40 +04:00
|
|
|
/*
|
|
|
|
Mapping of some of the python < 2.x PyString* functions to py3k's PyUnicode.
|
|
|
|
|
|
|
|
The commented names below represent those that are present in the PyBytes
|
|
|
|
definitions for python < 2.6 (below in this file) that don't have a direct
|
|
|
|
implementation.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define PyStringObject PyUnicodeObject
|
|
|
|
#define PyString_Type PyUnicode_Type
|
|
|
|
|
|
|
|
#define PyString_Check PyUnicode_Check
|
|
|
|
#define PyString_CheckExact PyUnicode_CheckExact
|
|
|
|
#define PyString_CHECK_INTERNED PyUnicode_CHECK_INTERNED
|
|
|
|
#define PyString_AS_STRING PyUnicode_AsLatin1String
|
|
|
|
#define PyString_GET_SIZE PyUnicode_GET_SIZE
|
|
|
|
|
|
|
|
#define PyString_FromStringAndSize PyUnicode_FromStringAndSize
|
|
|
|
#define PyString_FromString PyUnicode_FromString
|
|
|
|
#define PyString_FromFormatV PyUnicode_FromFormatV
|
|
|
|
#define PyString_FromFormat PyUnicode_FromFormat
|
|
|
|
/* #define PyString_Size PyUnicode_GET_SIZE */
|
|
|
|
/* #define PyString_AsString */
|
|
|
|
/* #define PyString_Repr */
|
|
|
|
#define PyString_Concat PyUnicode_Concat
|
|
|
|
#define PyString_ConcatAndDel PyUnicode_AppendAndDel
|
|
|
|
#define _PyString_Resize PyUnicode_Resize
|
|
|
|
/* #define _PyString_Eq */
|
|
|
|
#define PyString_Format PyUnicode_Format
|
|
|
|
/* #define _PyString_FormatLong */
|
|
|
|
/* #define PyString_DecodeEscape */
|
|
|
|
#define _PyString_Join PyUnicode_Join
|
|
|
|
#define PyString_Decode PyUnicode_Decode
|
|
|
|
#define PyString_Encode PyUnicode_Encode
|
|
|
|
#define PyString_AsEncodedObject PyUnicode_AsEncodedObject
|
|
|
|
#define PyString_AsEncodedString PyUnicode_AsEncodedString
|
|
|
|
#define PyString_AsDecodedObject PyUnicode_AsDecodedObject
|
|
|
|
#define PyString_AsDecodedString PyUnicode_AsDecodedUnicode
|
|
|
|
/* #define PyString_AsStringAndSize */
|
|
|
|
#define _PyString_InsertThousandsGrouping _PyUnicode_InsertThousandsGrouping
|
|
|
|
|
2010-06-16 02:49:56 +04:00
|
|
|
#endif /* PY_MAJOR_VERSION */
|
|
|
|
|
parsers: inline fields of dirstate values in C version
Previously, while unpacking the dirstate we'd create 3-4 new CPython objects
for most dirstate values:
- the state is a single character string, which is pooled by CPython
- the mode is a new object if it isn't 0 due to being in the lookup set
- the size is a new object if it is greater than 255
- the mtime is a new object if it isn't -1 due to being in the lookup set
- the tuple to contain them all
In some cases such as regular hg status, we actually look at all the objects.
In other cases like hg add, hg status for a subdirectory, or hg status with the
third-party hgwatchman enabled, we look at almost none of the objects.
This patch eliminates most object creation in these cases by defining a custom
C struct that is exposed to Python with an interface similar to a tuple. Only
when tuple elements are actually requested are the respective objects created.
The gains, where they're expected, are significant. The following tests are run
against a working copy with over 270,000 files.
parse_dirstate becomes significantly faster:
$ hg perfdirstate
before: wall 0.186437 comb 0.180000 user 0.160000 sys 0.020000 (best of 35)
after: wall 0.093158 comb 0.100000 user 0.090000 sys 0.010000 (best of 95)
and as a result, several commands benefit:
$ time hg status # with hgwatchman enabled
before: 0.42s user 0.14s system 99% cpu 0.563 total
after: 0.34s user 0.12s system 99% cpu 0.471 total
$ time hg add new-file
before: 0.85s user 0.18s system 99% cpu 1.033 total
after: 0.76s user 0.17s system 99% cpu 0.931 total
There is a slight regression in regular status performance, but this is fixed
in an upcoming patch.
2014-05-28 01:27:41 +04:00
|
|
|
typedef struct {
|
|
|
|
PyObject_HEAD
|
|
|
|
char state;
|
|
|
|
int mode;
|
|
|
|
int size;
|
|
|
|
int mtime;
|
|
|
|
} dirstateTupleObject;
|
|
|
|
|
2014-07-03 21:05:04 +04:00
|
|
|
extern PyTypeObject dirstateTupleType;
|
parsers: inline fields of dirstate values in C version
Previously, while unpacking the dirstate we'd create 3-4 new CPython objects
for most dirstate values:
- the state is a single character string, which is pooled by CPython
- the mode is a new object if it isn't 0 due to being in the lookup set
- the size is a new object if it is greater than 255
- the mtime is a new object if it isn't -1 due to being in the lookup set
- the tuple to contain them all
In some cases such as regular hg status, we actually look at all the objects.
In other cases like hg add, hg status for a subdirectory, or hg status with the
third-party hgwatchman enabled, we look at almost none of the objects.
This patch eliminates most object creation in these cases by defining a custom
C struct that is exposed to Python with an interface similar to a tuple. Only
when tuple elements are actually requested are the respective objects created.
The gains, where they're expected, are significant. The following tests are run
against a working copy with over 270,000 files.
parse_dirstate becomes significantly faster:
$ hg perfdirstate
before: wall 0.186437 comb 0.180000 user 0.160000 sys 0.020000 (best of 35)
after: wall 0.093158 comb 0.100000 user 0.090000 sys 0.010000 (best of 95)
and as a result, several commands benefit:
$ time hg status # with hgwatchman enabled
before: 0.42s user 0.14s system 99% cpu 0.563 total
after: 0.34s user 0.12s system 99% cpu 0.471 total
$ time hg add new-file
before: 0.85s user 0.18s system 99% cpu 1.033 total
after: 0.76s user 0.17s system 99% cpu 0.931 total
There is a slight regression in regular status performance, but this is fixed
in an upcoming patch.
2014-05-28 01:27:41 +04:00
|
|
|
#define dirstate_tuple_check(op) (Py_TYPE(op) == &dirstateTupleType)
|
|
|
|
|
2015-04-03 05:17:32 +03:00
|
|
|
/* This should be kept in sync with normcasespecs in encoding.py. */
|
|
|
|
enum normcase_spec {
|
|
|
|
NORMCASE_LOWER = -1,
|
|
|
|
NORMCASE_UPPER = 1,
|
|
|
|
NORMCASE_OTHER = 0
|
|
|
|
};
|
|
|
|
|
2015-03-24 21:00:09 +03:00
|
|
|
#define MIN(a, b) (((a)<(b))?(a):(b))
|
2015-03-25 22:16:10 +03:00
|
|
|
/* VC9 doesn't include bool and lacks stdbool.h based on my searching */
|
2015-04-21 06:21:57 +03:00
|
|
|
#if defined(_MSC_VER) || __STDC_VERSION__ < 199901L
|
2015-03-25 22:16:10 +03:00
|
|
|
#define true 1
|
|
|
|
#define false 0
|
|
|
|
typedef unsigned char bool;
|
|
|
|
#else
|
|
|
|
#include <stdbool.h>
|
|
|
|
#endif
|
|
|
|
|
2010-06-16 02:49:56 +04:00
|
|
|
#endif /* _HG_UTIL_H_ */
|