* These algorithms use special sorting. They are not called unless the * underlying sort function for the type is available. Note that axis is * already valid. The sort functions require 1-d contiguous and well-behaved * data. Therefore, a copy will be made of the data if needed before handing * it to the sorting routine. An iterator is constructed and adjusted to walk * over all but the
| 1140 | * over all but the desired sorting axis. |
| 1141 | */ |
| 1142 | static int |
| 1143 | _new_sortlike(PyArrayObject *op, int axis, PyArray_SortFunc *sort, |
| 1144 | PyArray_PartitionFunc *part, npy_intp const *kth, npy_intp nkth) |
| 1145 | { |
| 1146 | npy_intp N = PyArray_DIM(op, axis); |
| 1147 | npy_intp elsize = (npy_intp)PyArray_ITEMSIZE(op); |
| 1148 | npy_intp astride = PyArray_STRIDE(op, axis); |
| 1149 | int swap = PyArray_ISBYTESWAPPED(op); |
| 1150 | int is_aligned = IsAligned(op); |
| 1151 | int needcopy = !is_aligned || swap || astride != elsize; |
| 1152 | int needs_api = PyDataType_FLAGCHK(PyArray_DESCR(op), NPY_NEEDS_PYAPI); |
| 1153 | |
| 1154 | char *buffer = NULL; |
| 1155 | |
| 1156 | PyArrayIterObject *it; |
| 1157 | npy_intp size; |
| 1158 | |
| 1159 | int ret = 0; |
| 1160 | |
| 1161 | PyArray_Descr *descr = PyArray_DESCR(op); |
| 1162 | PyArray_Descr *odescr = NULL; |
| 1163 | |
| 1164 | NPY_cast_info to_cast_info = {.func = NULL}; |
| 1165 | NPY_cast_info from_cast_info = {.func = NULL}; |
| 1166 | |
| 1167 | NPY_BEGIN_THREADS_DEF; |
| 1168 | |
| 1169 | /* Check if there is any sorting to do */ |
| 1170 | if (N <= 1 || PyArray_SIZE(op) == 0) { |
| 1171 | return 0; |
| 1172 | } |
| 1173 | |
| 1174 | PyObject *mem_handler = PyDataMem_GetHandler(); |
| 1175 | if (mem_handler == NULL) { |
| 1176 | return -1; |
| 1177 | } |
| 1178 | it = (PyArrayIterObject *)PyArray_IterAllButAxis((PyObject *)op, &axis); |
| 1179 | if (it == NULL) { |
| 1180 | Py_DECREF(mem_handler); |
| 1181 | return -1; |
| 1182 | } |
| 1183 | size = it->size; |
| 1184 | |
| 1185 | if (needcopy) { |
| 1186 | buffer = PyDataMem_UserNEW(N * elsize, mem_handler); |
| 1187 | if (buffer == NULL) { |
| 1188 | ret = -1; |
| 1189 | goto fail; |
| 1190 | } |
| 1191 | if (PyDataType_FLAGCHK(descr, NPY_NEEDS_INIT)) { |
| 1192 | memset(buffer, 0, N * elsize); |
| 1193 | } |
| 1194 | |
| 1195 | if (swap) { |
| 1196 | odescr = PyArray_DescrNewByteorder(descr, NPY_SWAP); |
| 1197 | } |
| 1198 | else { |
| 1199 | odescr = descr; |
no test coverage detected