Show More
@@ -2874,169 +2874,6 b' bail:' | |||
|
2874 | 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 | 2877 | static Revlog_CAPI CAPI = { |
|
3041 | 2878 | /* increment the abi_version field upon each change in the Revlog_CAPI |
|
3042 | 2879 | struct or in the ABI of the listed functions */ |
@@ -3070,13 +2907,4 b' void revlog_module_init(PyObject *mod)' | |||
|
3070 | 2907 | caps = PyCapsule_New(&CAPI, "mercurial.cext.parsers.revlog_CAPI", NULL); |
|
3071 | 2908 | if (caps != NULL) |
|
3072 | 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