Skip to content

Commit 0665403

Browse files
committed
Added C++ backend for ArrayForTrees
1 parent b0f44b2 commit 0665403

File tree

2 files changed

+112
-5
lines changed

2 files changed

+112
-5
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#ifndef LINEAR_DATA_STRUCTURES_ARRAYFORTREES_HPP
2+
#define LINEAR_DATA_STRUCTURES_ARRAYFORTREES_HPP
3+
4+
#define PY_SSIZE_T_CLEAN
5+
#include <Python.h>
6+
#include <structmember.h>
7+
#include "DynamicOneDimensionalArray.hpp"
8+
#include "OneDimensionalArray.hpp"
9+
10+
typedef struct {
11+
PyObject_HEAD
12+
} ArrayForTrees;
13+
14+
static void ArrayForTrees_dealloc(ArrayForTrees *self) {
15+
Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
16+
}
17+
18+
static PyObject* ArrayForTrees__modify(ArrayForTrees *self) {
19+
if(((double)self->_num/(double)self->_size) < self->_load_factor){
20+
map<long , long> new_indices;
21+
22+
// PyObject* arr_new = OneDimensionalArray___new__(self->_dtype, 2*self->_num + 1);
23+
// This is how arr_new was made in DynamicOneDimensionalArray__modify() for the exact same line :-
24+
long new_size = 2 * self->_num + 1;
25+
PyObject** arr_new = reinterpret_cast<PyObject**>(std::malloc(new_size * sizeof(PyObject*)));
26+
for( i = 0; i < new_size; i++ ) {
27+
Py_INCREF(Py_None);
28+
arr_new[i] = Py_None;
29+
}
30+
31+
int j=0;
32+
PyObject** _data = self->_one_dimensional_array->_data;
33+
for(int i=0; i<=self->_last_pos_filled;i++){
34+
if(_data[i] != Py_None){ // Check this line. Python code: if self[i] is not None:
35+
Py_INCREF(Py_None); // This was put in DynamicOneDimensionalArray line 116
36+
arr_new[j] = _data[i];
37+
new_indices[_data[i]->key] = j;
38+
j += 1;
39+
}
40+
}
41+
for(int i=0;i<j;i++){
42+
if(arr_new[i]->left != Py_None){
43+
arr_new[i]->left = new_indices[_data[arr_new[i]->left]->key];
44+
}
45+
if(arr_new[i]->right != Py_None){
46+
arr_new[i]->right = new_indices[_data[arr_new[i]->right]->key];
47+
}
48+
if(arr_new[i]->parent != Py_None){
49+
arr_new[i]->parent = new_indices[_data[arr_new[i]->parent]->key];
50+
}
51+
}
52+
self->_last_pos_filled = j - 1;
53+
self->_one_dimensional_array->_data = arr_new;
54+
self->_one_dimensional_array->_size = new_size;
55+
self->_size = new_size;
56+
return reinterpret_cast<PyObject*>(new_indices);
57+
}
58+
Py_INCREF(Py_None);
59+
return Py_None;
60+
}
61+
62+
static struct PyMethodDef ArrayForTrees_PyMethodDef[] = {
63+
{"_modify", (PyCFunction) ArrayForTrees__modify, METH_VARARGS, NULL},
64+
{NULL}
65+
};
66+
67+
static PyTypeObject ArrayForTreesType = {
68+
/* tp_name */ PyVarObject_HEAD_INIT(NULL, 0) "ArrayForTrees",
69+
/* tp_basicsize */ sizeof(ArrayForTrees),
70+
/* tp_itemsize */ 0,
71+
/* tp_dealloc */ (destructor) ArrayForTrees_dealloc,
72+
/* tp_print */ 0,
73+
/* tp_getattr */ 0,
74+
/* tp_setattr */ 0,
75+
/* tp_reserved */ 0,
76+
/* tp_repr */ 0,
77+
/* tp_as_number */ 0,
78+
/* tp_as_sequence */ 0,
79+
/* tp_as_mapping */ 0,
80+
/* tp_hash */ 0,
81+
/* tp_call */ 0,
82+
/* tp_str */ 0,
83+
/* tp_getattro */ 0,
84+
/* tp_setattro */ 0,
85+
/* tp_as_buffer */ 0,
86+
/* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
87+
/* tp_doc */ 0,
88+
/* tp_traverse */ 0,
89+
/* tp_clear */ 0,
90+
/* tp_richcompare */ 0,
91+
/* tp_weaklistoffset */ 0,
92+
/* tp_iter */ 0,
93+
/* tp_iternext */ 0,
94+
/* tp_methods */ ArrayForTrees_PyMethodDef,
95+
/* tp_members */ 0,
96+
/* tp_getset */ 0,
97+
/* tp_base */ &DynamicOneDimensionalArrayType,
98+
/* tp_dict */ 0,
99+
/* tp_descr_get */ 0,
100+
/* tp_descr_set */ 0,
101+
/* tp_dictoffset */ 0,
102+
/* tp_init */ 0,
103+
/* tp_alloc */ 0,
104+
/* tp_new */ 0,
105+
};
106+
107+
#endif

pydatastructs/utils/_backend/cpp/TreeNode.hpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,18 @@ typedef struct {
1010
PyObject_HEAD
1111
long key;
1212
long data;
13-
PyObject* left;
14-
PyObject* right;
13+
PyObject* left; // can store None or a number
14+
PyObject* right; // can store None or a number
1515
bool is_root;
1616
long height;
1717
PyObject* parent;
1818
long size;
1919
} TreeNode;
2020

2121
static void TreeNode_dealloc(TreeNode *self) {
22-
// Dealloc left and right TreeNodes
23-
TreeNode_dealloc(reinterpret_cast<TreeNode*>(TreeNode->left));
24-
TreeNode_dealloc(reinterpret_cast<TreeNode*>(TreeNode->right));
22+
// left and right are long values, no need to dealloc for them
23+
// TreeNode_dealloc(reinterpret_cast<TreeNode*>(TreeNode->left));
24+
// TreeNode_dealloc(reinterpret_cast<TreeNode*>(TreeNode->right));
2525
// Check if other deallocs are needed using Py_XDECREF
2626
Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
2727
}

0 commit comments

Comments
 (0)