Skip to content

Commit 1e8d0ef

Browse files
update insertion sort llvm function
1 parent eef21ca commit 1e8d0ef

File tree

1 file changed

+78
-92
lines changed

1 file changed

+78
-92
lines changed

pydatastructs/linear_data_structures/_backend/cpp/algorithms/quadratic_time_sort.hpp

Lines changed: 78 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,7 @@ static PyObject* insertion_sort_llvm(PyObject* self, PyObject* args, PyObject* k
763763
if (PyObject_HasAttrString(arr_obj, "_data")) {
764764
buffer_obj = PyObject_GetAttrString(arr_obj, "_data");
765765
is_dynamic = true;
766+
if (!buffer_obj) return NULL;
766767
} else {
767768
Py_INCREF(buffer_obj);
768769
}
@@ -783,7 +784,6 @@ static PyObject* insertion_sort_llvm(PyObject* self, PyObject* args, PyObject* k
783784
PyLong_Check(first) ? "int32" :
784785
PyFloat_Check(first) ? "float64" : NULL
785786
);
786-
787787
Py_DECREF(first);
788788

789789
if (!inferred_dtype) {
@@ -792,139 +792,125 @@ static PyObject* insertion_sort_llvm(PyObject* self, PyObject* args, PyObject* k
792792
return NULL;
793793
}
794794

795+
// Import llvm_algorithms module and get function pointer
795796
PyObject* sys = PyImport_ImportModule("sys");
797+
if (!sys) { Py_DECREF(buffer_obj); return NULL; }
796798
PyObject* sys_path = PyObject_GetAttrString(sys, "path");
797799
Py_DECREF(sys);
800+
if (!sys_path) { Py_DECREF(buffer_obj); return NULL; }
798801

799-
Py_ssize_t original_len = PyList_Size(sys_path);
800-
if (original_len == -1) {
801-
Py_DECREF(sys_path);
802-
return NULL;
803-
}
802+
Py_ssize_t orig_len = PyList_Size(sys_path);
803+
if (orig_len == -1) { Py_DECREF(sys_path); Py_DECREF(buffer_obj); return NULL; }
804804

805805
PyObject* path = PyUnicode_FromString("pydatastructs/linear_data_structures/_backend/cpp/algorithms");
806-
if (!path) {
807-
Py_DECREF(sys_path);
808-
return NULL;
809-
}
810-
811-
int append_result = PyList_Append(sys_path, path);
806+
if (!path) { Py_DECREF(sys_path); Py_DECREF(buffer_obj); return NULL; }
807+
PyList_Append(sys_path, path);
812808
Py_DECREF(path);
813-
if (append_result != 0) {
814-
Py_DECREF(sys_path);
815-
return NULL;
816-
}
817809

818810
PyObject* mod = PyImport_ImportModule("llvm_algorithms");
819-
820-
if (PyList_SetSlice(sys_path, original_len, original_len + 1, NULL) != 0) {
821-
PyErr_Clear();
822-
}
811+
if (!mod) { Py_DECREF(sys_path); Py_DECREF(buffer_obj); return NULL; }
812+
PyList_SetSlice(sys_path, orig_len, orig_len+1, NULL); // cleanup
823813
Py_DECREF(sys_path);
824814

825815
PyObject* fn = PyObject_GetAttrString(mod, "get_insertion_sort_ptr");
826816
Py_DECREF(mod);
817+
if (!fn) { Py_DECREF(buffer_obj); return NULL; }
827818

828819
PyObject* arg = PyUnicode_FromString(inferred_dtype);
829-
if (!arg) {
830-
Py_DECREF(fn);
831-
return NULL;
832-
}
820+
if (!arg) { Py_DECREF(fn); Py_DECREF(buffer_obj); return NULL; }
833821

834822
PyObject* addr_obj = PyObject_CallFunctionObjArgs(fn, arg, NULL);
835823
Py_DECREF(fn);
836824
Py_DECREF(arg);
837-
if (!addr_obj) {
838-
Py_DECREF(buffer_obj);
839-
return NULL;
840-
}
825+
if (!addr_obj) { Py_DECREF(buffer_obj); return NULL; }
841826

842827
long long addr = PyLong_AsLongLong(addr_obj);
843828
Py_DECREF(addr_obj);
844-
845-
if (PyErr_Occurred()) {
846-
Py_DECREF(buffer_obj);
847-
return NULL;
848-
}
849-
850-
if (strcmp(inferred_dtype, "int32") == 0) {
851-
typedef void (*fn_t)(int*, int);
852-
fn_t insertion_sort_fn = (fn_t)(intptr_t)addr;
853-
int* arr = (int*)malloc(sizeof(int) * arr_len);
854-
for (Py_ssize_t i = 0; i < arr_len; i++) {
855-
PyObject* item = PySequence_GetItem(buffer_obj, i);
856-
arr[i] = (int)PyLong_AsLong(item);
857-
Py_DECREF(item);
858-
}
859-
insertion_sort_fn(arr, (int)arr_len);
860-
for (Py_ssize_t i = 0; i < arr_len; i++) {
861-
PyObject* v = PyLong_FromLong(arr[i]);
862-
PySequence_SetItem(buffer_obj, i, v);
863-
Py_DECREF(v);
864-
}
865-
free(arr);
866-
} else if (strcmp(inferred_dtype, "int64") == 0) {
867-
typedef void (*fn_t)(long long*, int);
868-
fn_t insertion_sort_fn = (fn_t)(intptr_t)addr;
869-
long long* arr = (long long*)malloc(sizeof(long long) * arr_len);
870-
for (Py_ssize_t i = 0; i < arr_len; i++) {
871-
PyObject* item = PySequence_GetItem(buffer_obj, i);
872-
arr[i] = PyLong_AsLongLong(item);
873-
Py_DECREF(item);
874-
}
875-
insertion_sort_fn(arr, (int)arr_len);
876-
for (Py_ssize_t i = 0; i < arr_len; i++) {
877-
PyObject* v = PyLong_FromLongLong(arr[i]);
878-
PySequence_SetItem(buffer_obj, i, v);
879-
Py_DECREF(v);
880-
}
881-
free(arr);
882-
} else if (strcmp(inferred_dtype, "float32") == 0) {
883-
typedef void (*fn_t)(float*, int);
884-
fn_t insertion_sort_fn = (fn_t)(intptr_t)addr;
885-
float* arr = (float*)malloc(sizeof(float) * arr_len);
886-
for (Py_ssize_t i = 0; i < arr_len; i++) {
887-
PyObject* item = PySequence_GetItem(buffer_obj, i);
829+
if (PyErr_Occurred()) { Py_DECREF(buffer_obj); return NULL; }
830+
831+
// Helper macro for type-safe execution
832+
#define RUN_SORT(TYPE, CAST) do { \
833+
TYPE* arr = (TYPE*)malloc(sizeof(TYPE) * arr_len); \
834+
if (!arr) { Py_DECREF(buffer_obj); PyErr_SetString(PyExc_MemoryError, "malloc failed"); return NULL; } \
835+
for (Py_ssize_t i=0;i<arr_len;i++) { \
836+
PyObject* item = PySequence_GetItem(buffer_obj, i); \
837+
if (!item) { free(arr); Py_DECREF(buffer_obj); return NULL; } \
838+
arr[i] = (CAST)PyLong_AsLong(item); \
839+
Py_DECREF(item); \
840+
if (PyErr_Occurred()) { free(arr); Py_DECREF(buffer_obj); return NULL; } \
841+
} \
842+
typedef void (*fn_t)(TYPE*, int); \
843+
fn_t sort_fn = (fn_t)(intptr_t)addr; \
844+
sort_fn(arr, (int)arr_len); \
845+
for (Py_ssize_t i=0;i<arr_len;i++) { \
846+
PyObject* v = PyLong_FromLong((long)arr[i]); \
847+
if (!v) { free(arr); Py_DECREF(buffer_obj); return NULL; } \
848+
int res = PyObject_SetItem(buffer_obj, PyLong_FromSsize_t(i), v); \
849+
Py_DECREF(v); \
850+
if (res < 0) { free(arr); Py_DECREF(buffer_obj); return NULL; } \
851+
} \
852+
free(arr); \
853+
} while(0)
854+
855+
if (strcmp(inferred_dtype,"int32")==0) {
856+
RUN_SORT(int,int);
857+
} else if (strcmp(inferred_dtype,"int64")==0) {
858+
RUN_SORT(long long,long long);
859+
} else if (strcmp(inferred_dtype,"float32")==0) {
860+
// float version
861+
float* arr = (float*)malloc(sizeof(float)*arr_len);
862+
if (!arr) { Py_DECREF(buffer_obj); PyErr_SetString(PyExc_MemoryError,"malloc failed"); return NULL; }
863+
for(Py_ssize_t i=0;i<arr_len;i++){
864+
PyObject* item = PySequence_GetItem(buffer_obj,i);
865+
if(!item){ free(arr); Py_DECREF(buffer_obj); return NULL; }
888866
arr[i] = (float)PyFloat_AsDouble(item);
889867
Py_DECREF(item);
868+
if(PyErr_Occurred()){ free(arr); Py_DECREF(buffer_obj); return NULL; }
890869
}
891-
insertion_sort_fn(arr, (int)arr_len);
892-
for (Py_ssize_t i = 0; i < arr_len; i++) {
870+
typedef void (*fn_t)(float*,int);
871+
fn_t sort_fn = (fn_t)(intptr_t)addr;
872+
sort_fn(arr,(int)arr_len);
873+
for(Py_ssize_t i=0;i<arr_len;i++){
893874
PyObject* v = PyFloat_FromDouble(arr[i]);
894-
PySequence_SetItem(buffer_obj, i, v);
875+
if(!v){ free(arr); Py_DECREF(buffer_obj); return NULL; }
876+
int res = PyObject_SetItem(buffer_obj, PyLong_FromSsize_t(i), v);
895877
Py_DECREF(v);
878+
if(res<0){ free(arr); Py_DECREF(buffer_obj); return NULL; }
896879
}
897880
free(arr);
898-
} else if (strcmp(inferred_dtype, "float64") == 0) {
899-
typedef void (*fn_t)(double*, int);
900-
fn_t insertion_sort_fn = (fn_t)(intptr_t)addr;
901-
double* arr = (double*)malloc(sizeof(double) * arr_len);
902-
for (Py_ssize_t i = 0; i < arr_len; i++) {
903-
PyObject* item = PySequence_GetItem(buffer_obj, i);
881+
} else if (strcmp(inferred_dtype,"float64")==0){
882+
double* arr = (double*)malloc(sizeof(double)*arr_len);
883+
if(!arr){ Py_DECREF(buffer_obj); PyErr_SetString(PyExc_MemoryError,"malloc failed"); return NULL; }
884+
for(Py_ssize_t i=0;i<arr_len;i++){
885+
PyObject* item = PySequence_GetItem(buffer_obj,i);
886+
if(!item){ free(arr); Py_DECREF(buffer_obj); return NULL; }
904887
arr[i] = PyFloat_AsDouble(item);
905888
Py_DECREF(item);
889+
if(PyErr_Occurred()){ free(arr); Py_DECREF(buffer_obj); return NULL; }
906890
}
907-
insertion_sort_fn(arr, (int)arr_len);
908-
for (Py_ssize_t i = 0; i < arr_len; i++) {
891+
typedef void (*fn_t)(double*,int);
892+
fn_t sort_fn = (fn_t)(intptr_t)addr;
893+
sort_fn(arr,(int)arr_len);
894+
for(Py_ssize_t i=0;i<arr_len;i++){
909895
PyObject* v = PyFloat_FromDouble(arr[i]);
910-
PySequence_SetItem(buffer_obj, i, v);
896+
if(!v){ free(arr); Py_DECREF(buffer_obj); return NULL; }
897+
int res = PyObject_SetItem(buffer_obj, PyLong_FromSsize_t(i), v);
911898
Py_DECREF(v);
899+
if(res<0){ free(arr); Py_DECREF(buffer_obj); return NULL; }
912900
}
913901
free(arr);
914902
} else {
915903
Py_DECREF(buffer_obj);
916-
PyErr_SetString(PyExc_TypeError, "Unsupported dtype for insertion_sort_llvm");
904+
PyErr_SetString(PyExc_TypeError,"Unsupported dtype for insertion_sort_llvm");
917905
return NULL;
918906
}
919907

920-
if (is_dynamic && PyObject_HasAttrString(arr_obj, "_modify")) {
921-
PyObject* modify_fn = PyObject_GetAttrString(arr_obj, "_modify");
922-
if (modify_fn) {
923-
PyObject_CallFunctionObjArgs(modify_fn, NULL);
908+
if(is_dynamic && PyObject_HasAttrString(arr_obj,"_modify")){
909+
PyObject* modify_fn = PyObject_GetAttrString(arr_obj,"_modify");
910+
if(modify_fn){
911+
PyObject_CallFunctionObjArgs(modify_fn,NULL);
924912
Py_DECREF(modify_fn);
925-
} else {
926-
PyErr_Clear();
927-
}
913+
} else { PyErr_Clear(); }
928914
}
929915

930916
Py_DECREF(buffer_obj);

0 commit comments

Comments
 (0)