Show More
@@ -2874,169 +2874,6 b' bail:' | |||||
2874 | return NULL; |
|
2874 | return NULL; | |
2875 | } |
|
2875 | } | |
2876 |
|
2876 | |||
2877 | #ifdef WITH_RUST |
|
|||
2878 |
|
||||
2879 | /* rustlazyancestors: iteration over ancestors implemented in Rust |
|
|||
2880 | * |
|
|||
2881 | * This class holds a reference to an index and to the Rust iterator. |
|
|||
2882 | */ |
|
|||
2883 | typedef struct rustlazyancestorsObjectStruct rustlazyancestorsObject; |
|
|||
2884 |
|
||||
2885 | struct rustlazyancestorsObjectStruct { |
|
|||
2886 | PyObject_HEAD |
|
|||
2887 | /* Type-specific fields go here. */ |
|
|||
2888 | indexObject *index; /* Ref kept to avoid GC'ing the index */ |
|
|||
2889 | void *iter; /* Rust iterator */ |
|
|||
2890 | }; |
|
|||
2891 |
|
||||
2892 | /* FFI exposed from Rust code */ |
|
|||
2893 | rustlazyancestorsObject *rustlazyancestors_init(indexObject *index, |
|
|||
2894 | /* intrevs vector */ |
|
|||
2895 | Py_ssize_t initrevslen, |
|
|||
2896 | long *initrevs, long stoprev, |
|
|||
2897 | int inclusive); |
|
|||
2898 | void rustlazyancestors_drop(rustlazyancestorsObject *self); |
|
|||
2899 | int rustlazyancestors_next(rustlazyancestorsObject *self); |
|
|||
2900 | int rustlazyancestors_contains(rustlazyancestorsObject *self, long rev); |
|
|||
2901 |
|
||||
2902 | /* CPython instance methods */ |
|
|||
2903 | static int rustla_init(rustlazyancestorsObject *self, PyObject *args) |
|
|||
2904 | { |
|
|||
2905 | PyObject *initrevsarg = NULL; |
|
|||
2906 | PyObject *inclusivearg = NULL; |
|
|||
2907 | long stoprev = 0; |
|
|||
2908 | long *initrevs = NULL; |
|
|||
2909 | int inclusive = 0; |
|
|||
2910 | Py_ssize_t i; |
|
|||
2911 |
|
||||
2912 | indexObject *index; |
|
|||
2913 | if (!PyArg_ParseTuple(args, "O!O!lO!", &HgRevlogIndex_Type, &index, |
|
|||
2914 | &PyList_Type, &initrevsarg, &stoprev, |
|
|||
2915 | &PyBool_Type, &inclusivearg)) |
|
|||
2916 | return -1; |
|
|||
2917 |
|
||||
2918 | Py_INCREF(index); |
|
|||
2919 | self->index = index; |
|
|||
2920 |
|
||||
2921 | if (inclusivearg == Py_True) |
|
|||
2922 | inclusive = 1; |
|
|||
2923 |
|
||||
2924 | Py_ssize_t linit = PyList_GET_SIZE(initrevsarg); |
|
|||
2925 |
|
||||
2926 | initrevs = (long *)calloc(linit, sizeof(long)); |
|
|||
2927 |
|
||||
2928 | if (initrevs == NULL) { |
|
|||
2929 | PyErr_NoMemory(); |
|
|||
2930 | goto bail; |
|
|||
2931 | } |
|
|||
2932 |
|
||||
2933 | for (i = 0; i < linit; i++) { |
|
|||
2934 | initrevs[i] = PyInt_AsLong(PyList_GET_ITEM(initrevsarg, i)); |
|
|||
2935 | } |
|
|||
2936 | if (PyErr_Occurred()) |
|
|||
2937 | goto bail; |
|
|||
2938 |
|
||||
2939 | self->iter = |
|
|||
2940 | rustlazyancestors_init(index, linit, initrevs, stoprev, inclusive); |
|
|||
2941 | if (self->iter == NULL) { |
|
|||
2942 | /* if this is because of GraphError::ParentOutOfRange |
|
|||
2943 | * HgRevlogIndex_GetParents() has already set the proper |
|
|||
2944 | * exception */ |
|
|||
2945 | goto bail; |
|
|||
2946 | } |
|
|||
2947 |
|
||||
2948 | free(initrevs); |
|
|||
2949 | return 0; |
|
|||
2950 |
|
||||
2951 | bail: |
|
|||
2952 | free(initrevs); |
|
|||
2953 | return -1; |
|
|||
2954 | }; |
|
|||
2955 |
|
||||
2956 | static void rustla_dealloc(rustlazyancestorsObject *self) |
|
|||
2957 | { |
|
|||
2958 | Py_XDECREF(self->index); |
|
|||
2959 | if (self->iter != NULL) { /* can happen if rustla_init failed */ |
|
|||
2960 | rustlazyancestors_drop(self->iter); |
|
|||
2961 | } |
|
|||
2962 | PyObject_Del(self); |
|
|||
2963 | } |
|
|||
2964 |
|
||||
2965 | static PyObject *rustla_next(rustlazyancestorsObject *self) |
|
|||
2966 | { |
|
|||
2967 | int res = rustlazyancestors_next(self->iter); |
|
|||
2968 | if (res == -1) { |
|
|||
2969 | /* Setting an explicit exception seems unnecessary |
|
|||
2970 | * as examples from Python source code (Objects/rangeobjets.c |
|
|||
2971 | * and Modules/_io/stringio.c) seem to demonstrate. |
|
|||
2972 | */ |
|
|||
2973 | return NULL; |
|
|||
2974 | } |
|
|||
2975 | return PyInt_FromLong(res); |
|
|||
2976 | } |
|
|||
2977 |
|
||||
2978 | static int rustla_contains(rustlazyancestorsObject *self, PyObject *rev) |
|
|||
2979 | { |
|
|||
2980 | long lrev; |
|
|||
2981 | if (!pylong_to_long(rev, &lrev)) { |
|
|||
2982 | PyErr_Clear(); |
|
|||
2983 | return 0; |
|
|||
2984 | } |
|
|||
2985 | return rustlazyancestors_contains(self->iter, lrev); |
|
|||
2986 | } |
|
|||
2987 |
|
||||
2988 | static PySequenceMethods rustla_sequence_methods = { |
|
|||
2989 | 0, /* sq_length */ |
|
|||
2990 | 0, /* sq_concat */ |
|
|||
2991 | 0, /* sq_repeat */ |
|
|||
2992 | 0, /* sq_item */ |
|
|||
2993 | 0, /* sq_slice */ |
|
|||
2994 | 0, /* sq_ass_item */ |
|
|||
2995 | 0, /* sq_ass_slice */ |
|
|||
2996 | (objobjproc)rustla_contains, /* sq_contains */ |
|
|||
2997 | }; |
|
|||
2998 |
|
||||
2999 | static PyTypeObject rustlazyancestorsType = { |
|
|||
3000 | PyVarObject_HEAD_INIT(NULL, 0) /* header */ |
|
|||
3001 | "parsers.rustlazyancestors", /* tp_name */ |
|
|||
3002 | sizeof(rustlazyancestorsObject), /* tp_basicsize */ |
|
|||
3003 | 0, /* tp_itemsize */ |
|
|||
3004 | (destructor)rustla_dealloc, /* tp_dealloc */ |
|
|||
3005 | 0, /* tp_print */ |
|
|||
3006 | 0, /* tp_getattr */ |
|
|||
3007 | 0, /* tp_setattr */ |
|
|||
3008 | 0, /* tp_compare */ |
|
|||
3009 | 0, /* tp_repr */ |
|
|||
3010 | 0, /* tp_as_number */ |
|
|||
3011 | &rustla_sequence_methods, /* tp_as_sequence */ |
|
|||
3012 | 0, /* tp_as_mapping */ |
|
|||
3013 | 0, /* tp_hash */ |
|
|||
3014 | 0, /* tp_call */ |
|
|||
3015 | 0, /* tp_str */ |
|
|||
3016 | 0, /* tp_getattro */ |
|
|||
3017 | 0, /* tp_setattro */ |
|
|||
3018 | 0, /* tp_as_buffer */ |
|
|||
3019 | Py_TPFLAGS_DEFAULT, /* tp_flags */ |
|
|||
3020 | "Iterator over ancestors, implemented in Rust", /* tp_doc */ |
|
|||
3021 | 0, /* tp_traverse */ |
|
|||
3022 | 0, /* tp_clear */ |
|
|||
3023 | 0, /* tp_richcompare */ |
|
|||
3024 | 0, /* tp_weaklistoffset */ |
|
|||
3025 | 0, /* tp_iter */ |
|
|||
3026 | (iternextfunc)rustla_next, /* tp_iternext */ |
|
|||
3027 | 0, /* tp_methods */ |
|
|||
3028 | 0, /* tp_members */ |
|
|||
3029 | 0, /* tp_getset */ |
|
|||
3030 | 0, /* tp_base */ |
|
|||
3031 | 0, /* tp_dict */ |
|
|||
3032 | 0, /* tp_descr_get */ |
|
|||
3033 | 0, /* tp_descr_set */ |
|
|||
3034 | 0, /* tp_dictoffset */ |
|
|||
3035 | (initproc)rustla_init, /* tp_init */ |
|
|||
3036 | 0, /* tp_alloc */ |
|
|||
3037 | }; |
|
|||
3038 | #endif /* WITH_RUST */ |
|
|||
3039 |
|
||||
3040 | static Revlog_CAPI CAPI = { |
|
2877 | static Revlog_CAPI CAPI = { | |
3041 | /* increment the abi_version field upon each change in the Revlog_CAPI |
|
2878 | /* increment the abi_version field upon each change in the Revlog_CAPI | |
3042 | struct or in the ABI of the listed functions */ |
|
2879 | struct or in the ABI of the listed functions */ | |
@@ -3070,13 +2907,4 b' void revlog_module_init(PyObject *mod)' | |||||
3070 | caps = PyCapsule_New(&CAPI, "mercurial.cext.parsers.revlog_CAPI", NULL); |
|
2907 | caps = PyCapsule_New(&CAPI, "mercurial.cext.parsers.revlog_CAPI", NULL); | |
3071 | if (caps != NULL) |
|
2908 | if (caps != NULL) | |
3072 | PyModule_AddObject(mod, "revlog_CAPI", caps); |
|
2909 | PyModule_AddObject(mod, "revlog_CAPI", caps); | |
3073 |
|
||||
3074 | #ifdef WITH_RUST |
|
|||
3075 | rustlazyancestorsType.tp_new = PyType_GenericNew; |
|
|||
3076 | if (PyType_Ready(&rustlazyancestorsType) < 0) |
|
|||
3077 | return; |
|
|||
3078 | Py_INCREF(&rustlazyancestorsType); |
|
|||
3079 | PyModule_AddObject(mod, "rustlazyancestors", |
|
|||
3080 | (PyObject *)&rustlazyancestorsType); |
|
|||
3081 | #endif |
|
|||
3082 | } |
|
2910 | } |
General Comments 0
You need to be logged in to leave comments.
Login now