Mercurial > hg
view mercurial/cext/util.h @ 46184:cb8b2ee89a5d
copies: stop attempt to avoid extra dict copies around branching
In the python code, we attempt to avoid unnecessary dict copies when gathering
copy information. However that logic is wobbly and I keep running into case
where independent branches affects each others.
With the current code we can't ensure we are the only "user" of dict when
dealing with merge.
This caused havoc in the next series on tests I am about to introduce.
So for now I am disabling the faulty optimisation. I believe we will need a
dedicated overlay to deal with the "copy on write logic" to have something
correct. I am also hoping to find time to build dedicated test case for this
category of problem instead of relying on side effect in other tests. However
for now I am focussing on another issue.
Differential Revision: https://phab.mercurial-scm.org/D9608
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Tue, 15 Dec 2020 00:29:29 +0100 |
parents | fa33196088c4 |
children | 84391ddf4c78 |
line wrap: on
line source
/* 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_ #include "compat.h" #if PY_MAJOR_VERSION >= 3 #define IS_PY3K #endif /* helper to switch things like string literal depending on Python version */ #ifdef IS_PY3K #define PY23(py2, py3) py3 #else #define PY23(py2, py3) py2 #endif /* clang-format off */ typedef struct { PyObject_HEAD char state; int mode; int size; int mtime; } dirstateTupleObject; /* clang-format on */ extern PyTypeObject dirstateTupleType; #define dirstate_tuple_check(op) (Py_TYPE(op) == &dirstateTupleType) #ifndef MIN #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif /* VC9 doesn't include bool and lacks stdbool.h based on my searching */ #if defined(_MSC_VER) || __STDC_VERSION__ < 199901L #define true 1 #define false 0 typedef unsigned char bool; #else #include <stdbool.h> #endif static inline PyObject *_dict_new_presized(Py_ssize_t expected_size) { /* _PyDict_NewPresized expects a minused parameter, but it actually creates a dictionary that's the nearest power of two bigger than the parameter. For example, with the initial minused = 1000, the dictionary created has size 1024. Of course in a lot of cases that can be greater than the maximum load factor Python's dict object expects (= 2/3), so as soon as we cross the threshold we'll resize anyway. So create a dictionary that's at least 3/2 the size. */ return _PyDict_NewPresized(((1 + expected_size) / 2) * 3); } /* Convert a PyInt or PyLong to a long. Returns false if there is an error, in which case an exception will already have been set. */ static inline bool pylong_to_long(PyObject *pylong, long *out) { *out = PyLong_AsLong(pylong); /* Fast path to avoid hitting PyErr_Occurred if the value was obviously * not an error. */ if (*out != -1) { return true; } return PyErr_Occurred() == NULL; } #endif /* _HG_UTIL_H_ */