3
3
API_t API_tree [NUM_OF_API_FUNCS ];
4
4
uint32_t API_cntr ;
5
5
6
+ uint32_t API_place_cntr ;
7
+
6
8
//macro to add new instruction to the instructions binary tree
7
9
#define create_instruction_data (name , desc ) \
8
10
const char *name##_API_NAME = (const char *)#name; \
@@ -45,6 +47,13 @@ void init_interpreter(void)
45
47
add_instruction (okor , kutya_func );
46
48
add_instruction (csiga , kutya_func );
47
49
50
+ // Index eache element to find their place in alphabetic order
51
+ index_apis_in_order ( & API_tree [0 ] );
52
+
53
+ // Optimise the API_tree to make it balanced
54
+ optimise_api_tree ( & API_tree [0 ] );
55
+
56
+ // Print the API list
48
57
print_apis_in_order ( & API_tree [0 ] );
49
58
50
59
if ( API_cntr != NUM_OF_API_FUNCS ){
@@ -78,8 +87,11 @@ void add_interpreter_instruction(const char **name, const char **desc, void (*fu
78
87
API_tree [0 ].desc = (const char * * )desc ; // address of the description string( char** type )
79
88
API_tree [0 ].func = func ; // function pointer to the actual function
80
89
81
- API_tree [0 ].left = NULL ; // because it is the first element of the tree,
82
- API_tree [0 ].right = NULL ; // left and right branches has to be NULL
90
+ API_tree [0 ].left = NULL ; // because it is the first element of the tree,
91
+ API_tree [0 ].right = NULL ; // left and right branches has to be NULL
92
+
93
+ API_tree [0 ].place = 0 ; // default place = 0
94
+
83
95
}
84
96
85
97
// if it is ot the first command we have to find it's place in the tree
@@ -102,25 +114,163 @@ void add_interpreter_instruction(const char **name, const char **desc, void (*fu
102
114
// link the new item on the previous branch
103
115
( comp_res > 0 ) ? ( ( prev -> left ) = & API_tree [API_cntr ] ) : ( ( prev -> right ) = & API_tree [API_cntr ] );
104
116
117
+ // Fill the new item parameters
118
+
105
119
API_tree [API_cntr ].name = (const char * * )name ; // address of the name string( char** type )
106
120
API_tree [API_cntr ].desc = (const char * * )desc ; // address of the description string( char** type )
107
121
API_tree [API_cntr ].func = func ; // function pointer to the actual function
108
122
109
- API_tree [API_cntr ].left = NULL ; // close the branch
123
+ API_tree [API_cntr ].left = NULL ; // close the branch
110
124
API_tree [API_cntr ].right = NULL ;
125
+
126
+ API_tree [API_cntr ].place = 0 ; // default place = 0
127
+
111
128
}
112
129
113
130
API_cntr ++ ;
114
131
115
132
}
116
133
134
+ // Creates indexes by alphabetical order for each element
135
+ // The result is stored in the 'place' variable inside the API_t structure
136
+ void index_apis_in_order (API_t * head ){
137
+
138
+ API_place_cntr = 0 ;
139
+
140
+ recursive_indexer ( head );
141
+
142
+ printf ( "Indexer finished...\r\n" );
143
+
144
+ }
145
+
146
+ // This function is used by the 'index_apis_in_order' function
147
+ void recursive_indexer (API_t * head ){
148
+
149
+ // End of recursive algorythm
150
+ if ( head == 0 ){
151
+
152
+ return ;
153
+
154
+ }
155
+
156
+ recursive_indexer ( head -> left );
157
+
158
+ head -> place = API_place_cntr ;
159
+ API_place_cntr ++ ;
160
+
161
+ recursive_indexer ( head -> right );
162
+
163
+ }
164
+
165
+ // This function is used to print out the API to the console
117
166
void print_apis_in_order (API_t * head ){
118
167
119
- if ( head == 0 ){
120
- return ;
168
+ // End of recursive algorythm
169
+ if ( head == 0 ){
170
+ return ;
121
171
}
122
172
123
- print_apis_in_order ( head -> left );
124
- printf ( "%s\r\n" , * (head -> name ) );
125
- print_apis_in_order ( head -> right );
173
+ print_apis_in_order ( head -> left );
174
+ printf ( "%d.\t%s\r\n" , head -> place , * (head -> name ) );
175
+ print_apis_in_order ( head -> right );
176
+
177
+ }
178
+
179
+ // Finds the array index( API_tree index ) by place( alphabetical order )
180
+ uint16_t find_api_index_by_place ( uint16_t place ){
181
+
182
+ uint16_t i ;
183
+
184
+ for ( i = 0 ; i < NUM_OF_API_FUNCS ; i ++ ){
185
+
186
+ if ( API_tree [i ].place == place ){
187
+
188
+ return i ;
189
+
190
+ }
191
+
192
+ }
193
+ return 0 ;
194
+ }
195
+
196
+ // This function is used to put an element in API_tree by index from place
197
+ // Example: to put the place=3 node to API_tree[0]
198
+ // swap_api_elements( 0, 3 );
199
+ void swap_api_elements ( uint16_t index , uint16_t place ){
200
+
201
+ API_t buffer ;
202
+ uint16_t current_index ;
203
+
204
+ // Find the index in the array by place of the 'i'-th element
205
+ current_index = find_api_index_by_place ( place );
206
+
207
+ // save the context of the 'i'-th element to the buffer
208
+ buffer = API_tree [index ];
209
+
210
+ // write the 'current_index'-th element to the 'i'-th element
211
+ API_tree [index ] = API_tree [current_index ];
212
+
213
+ // write the buffer to the 'current_index'-th element
214
+ API_tree [current_index ] = buffer ;
215
+
216
+ }
217
+
218
+ // This function is used to balance the API_tree to get the highest
219
+ // search performance
220
+ void optimise_api_tree (API_t * head ){
221
+
222
+ uint32_t i ;
223
+ API_t buffer ;
224
+
225
+ // recursive optimiser need to initialise 'API_cntr' to 0
226
+ API_cntr = 0 ;
227
+
228
+ // recursively finds the order which is optimal for a balanced tree
229
+ recursive_optimiser ( 0 , NUM_OF_API_FUNCS - 1 );
230
+
231
+
232
+ // The order is good, but the connection between the branches broken,
233
+ // because we swapped the API_tree array elements.
234
+ // To fix this problem we have to reinitialise the tree, and use
235
+ // 'add_interpreter_instruction' function again for all elements.
236
+ API_cntr = 0 ;
237
+ for ( i = 0 ; i < NUM_OF_API_FUNCS ; i ++ ){
238
+
239
+ // Put the data to the buffer then rewrite the data with fixed parameters.
240
+ buffer = API_tree [i ];
241
+
242
+ add_interpreter_instruction ( buffer .name , buffer .desc , buffer .func );
243
+
244
+ // Save the place data as well.
245
+ API_tree [i ].place = buffer .place ;
246
+
247
+ }
248
+ }
249
+
250
+ // This function is used to order the elements in API_tree array to
251
+ // get the fastest search speed
252
+ // this function needs 'API_cntr' to be zeroed out before the first call
253
+ void recursive_optimiser ( int32_t start_index , int32_t stop_index ){
254
+
255
+ int32_t mid ;
256
+
257
+ // End of recursive algorythm
258
+ if ( start_index > stop_index ){
259
+
260
+ return ;
261
+
262
+ }
263
+
264
+ // Find the middle of the intervall
265
+ mid = ( start_index + stop_index ) / 2 ;
266
+
267
+ // Put the right element to it's place
268
+ swap_api_elements ( API_cntr , mid );
269
+ API_cntr ++ ;
270
+
271
+ // Do some recursion for the other intervalls
272
+ recursive_optimiser ( start_index , mid - 1 );
273
+ recursive_optimiser ( mid + 1 , stop_index );
274
+
275
+
126
276
}
0 commit comments