php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
bst.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2018 Alexander Borisov
3 *
4 * Author: Alexander Borisov <borisov@lexbor.com>
5 */
6
7#include "lexbor/core/bst.h"
8#include "lexbor/core/conv.h"
9
10
13{
14 return lexbor_calloc(1, sizeof(lexbor_bst_t));
15}
16
19{
21
22 if (bst == NULL) {
24 }
25
26 if (size == 0) {
28 }
29
32 sizeof(lexbor_bst_entry_t));
33 if (status != LXB_STATUS_OK) {
34 return status;
35 }
36
37 bst->root = 0;
38 bst->tree_length = 0;
39
40 return LXB_STATUS_OK;
41}
42
43void
45{
46 if (bst != NULL) {
48
49 bst->root = 0;
50 bst->tree_length = 0;
51 }
52}
53
55lexbor_bst_destroy(lexbor_bst_t *bst, bool self_destroy)
56{
57 if (bst == NULL) {
58 return NULL;
59 }
60
61 bst->dobject = lexbor_dobject_destroy(bst->dobject, true);
62
63 if (self_destroy) {
64 return lexbor_free(bst);
65 }
66
67 return bst;
68}
69
72{
74 if (new_entry == NULL) {
75 return NULL;
76 }
77
78 new_entry->size = size;
79
80 bst->tree_length++;
81
82 return new_entry;
83}
84
87 size_t size, void *value)
88{
89 lexbor_bst_entry_t *new_entry, *entry;
90
91 new_entry = lexbor_dobject_calloc(bst->dobject);
92 if (new_entry == NULL) {
93 return NULL;
94 }
95
96 new_entry->size = size;
97 new_entry->value = value;
98
99 bst->tree_length++;
100
101 if (*scope == NULL) {
102 *scope = new_entry;
103 return new_entry;
104 }
105
106 entry = *scope;
107
108 while (entry != NULL) {
109 if (size == entry->size) {
110 if (entry->next) {
111 new_entry->next = entry->next;
112 }
113
114 entry->next = new_entry;
115 new_entry->parent = entry->parent;
116
117 return new_entry;
118 }
119 else if (size > entry->size) {
120 if (entry->right == NULL) {
121 entry->right = new_entry;
122 new_entry->parent = entry;
123
124 return new_entry;
125 }
126
127 entry = entry->right;
128 }
129 else {
130 if (entry->left == NULL) {
131 entry->left = new_entry;
132 new_entry->parent = entry;
133
134 return new_entry;
135 }
136
137 entry = entry->left;
138 }
139 }
140
141 return NULL;
142}
143
146 size_t size)
147{
148 lexbor_bst_entry_t *entry;
149
150 if (*scope == NULL) {
152
153 return *scope;
154 }
155
156 entry = *scope;
157
158 while (entry != NULL) {
159 if (size == entry->size) {
160 return entry;
161 }
162 else if (size > entry->size) {
163 if (entry->right == NULL) {
164 entry->right = lexbor_bst_entry_make(bst, size);
165 entry->right->parent = entry;
166
167 return entry->right;
168 }
169
170 entry = entry->right;
171 }
172 else {
173 if (entry->left == NULL) {
174 entry->left = lexbor_bst_entry_make(bst, size);
175 entry->left->parent = entry;
176
177 return entry->left;
178 }
179
180 entry = entry->left;
181 }
182 }
183
184 return NULL;
185}
186
189{
190 while (scope != NULL) {
191 if (scope->size == size) {
192 return scope;
193 }
194 else if (size > scope->size) {
195 scope = scope->right;
196 }
197 else {
198 scope = scope->left;
199 }
200 }
201
202 return NULL;
203}
204
207 size_t size)
208{
210
211 while (scope != NULL) {
212 if (scope->size == size) {
213 return scope;
214 }
215 else if (size > scope->size) {
216 scope = scope->right;
217 }
218 else {
219 max = scope;
220 scope = scope->left;
221 }
222 }
223
224 return max;
225}
226
227void *
229{
230 lexbor_bst_entry_t *entry = *scope;
231
232 while (entry != NULL) {
233 if (entry->size == size) {
234 return lexbor_bst_remove_by_pointer(bst, entry, scope);
235 }
236 else if (size > entry->size) {
237 entry = entry->right;
238 }
239 else {
240 entry = entry->left;
241 }
242 }
243
244 return NULL;
245}
246
247void *
249 size_t size, size_t *found_size)
250{
251 lexbor_bst_entry_t *entry = *scope;
253
254 while (entry != NULL) {
255 if (entry->size == size) {
256 if (found_size) {
257 *found_size = entry->size;
258 }
259
260 return lexbor_bst_remove_by_pointer(bst, entry, scope);
261 }
262 else if (size > entry->size) {
263 entry = entry->right;
264 }
265 else {
266 max = entry;
267 entry = entry->left;
268 }
269 }
270
271 if (max != NULL) {
272 if (found_size != NULL) {
273 *found_size = max->size;
274 }
275
277 }
278
279 if (found_size != NULL) {
280 *found_size = 0;
281 }
282
283 return NULL;
284}
285
286void *
288 lexbor_bst_entry_t **root)
289{
290 void *value;
292
293 bst->tree_length--;
294
295 if (entry->next != NULL) {
296 next = entry->next;
297 entry->next = entry->next->next;
298
299 value = next->value;
300
302
303 return value;
304 }
305
306 value = entry->value;
307
308 if (entry->left == NULL && entry->right == NULL) {
309 if (entry->parent != NULL) {
310 if (entry->parent->left == entry) entry->parent->left = NULL;
311 if (entry->parent->right == entry) entry->parent->right = NULL;
312 }
313 else {
314 *root = NULL;
315 }
316
317 lexbor_dobject_free(bst->dobject, entry);
318 }
319 else if (entry->left == NULL) {
320 if (entry->parent == NULL) {
321 entry->right->parent = NULL;
322
323 *root = entry->right;
324
325 lexbor_dobject_free(bst->dobject, entry);
326
327 entry = *root;
328 }
329 else {
330 right = entry->right;
331 right->parent = entry->parent;
332
333 memcpy(entry, right, sizeof(lexbor_bst_entry_t));
334
336 }
337
338 if (entry->right != NULL) {
339 entry->right->parent = entry;
340 }
341
342 if (entry->left != NULL) {
343 entry->left->parent = entry;
344 }
345 }
346 else if (entry->right == NULL) {
347 if (entry->parent == NULL) {
348 entry->left->parent = NULL;
349
350 *root = entry->left;
351
352 lexbor_dobject_free(bst->dobject, entry);
353
354 entry = *root;
355 }
356 else {
357 left = entry->left;
358 left->parent = entry->parent;
359
360 memcpy(entry, left, sizeof(lexbor_bst_entry_t));
361
363 }
364
365 if (entry->right != NULL) {
366 entry->right->parent = entry;
367 }
368
369 if (entry->left != NULL) {
370 entry->left->parent = entry;
371 }
372 }
373 else {
374 left = entry->right;
375
376 while (left->left != NULL) {
377 left = left->left;
378 }
379
380 /* Swap */
381 entry->size = left->size;
382 entry->next = left->next;
383 entry->value = left->value;
384
385 /* Change parrent */
386 if (entry->right == left) {
387 entry->right = left->right;
388
389 if (entry->right != NULL) {
390 left->right->parent = entry;
391 }
392 }
393 else {
394 left->parent->left = left->right;
395
396 if (left->right != NULL) {
397 left->right->parent = left->parent;
398 }
399 }
400
402 }
403
404 return value;
405}
406
407void
412
413void
415 lexbor_callback_f callback, void *ctx, size_t tabs)
416{
417 size_t len;
418 lxb_char_t buff[1024];
419
420 if (entry == NULL) {
421 return;
422 }
423
424 /* Left */
425 for (size_t i = 0; i < tabs; i++) {
426 callback((lxb_char_t *) "\t", 1, ctx);
427 }
428 callback((lxb_char_t *) "<left ", 6, ctx);
429
430 if (entry->left) {
431 len = lexbor_conv_int64_to_data((int64_t) entry->left->size,
432 buff, sizeof(buff));
433 callback(buff, len, ctx);
434
435 callback((lxb_char_t *) ">\n", 2, ctx);
436 lexbor_bst_serialize_entry(entry->left, callback, ctx, (tabs + 1));
437
438 for (size_t i = 0; i < tabs; i++) {
439 callback((lxb_char_t *) "\t", 1, ctx);
440 }
441 }
442 else {
443 callback((lxb_char_t *) "NULL>", 5, ctx);
444 }
445
446 callback((lxb_char_t *) "</left>\n", 8, ctx);
447
448 /* Right */
449 for (size_t i = 0; i < tabs; i++) {
450 callback((lxb_char_t *) "\t", 1, ctx);
451 }
452 callback((lxb_char_t *) "<right ", 7, ctx);
453
454 if (entry->right) {
455 len = lexbor_conv_int64_to_data((int64_t) entry->right->size,
456 buff, sizeof(buff));
457 callback(buff, len, ctx);
458
459 callback((lxb_char_t *) ">\n", 2, ctx);
460 lexbor_bst_serialize_entry(entry->right, callback, ctx, (tabs + 1));
461
462 for (size_t i = 0; i < tabs; i++) {
463 callback((lxb_char_t *) "\t", 1, ctx);
464 }
465 }
466 else {
467 callback((lxb_char_t *) "NULL>", 5, ctx);
468 }
469
470 callback((lxb_char_t *) "</right>\n", 9, ctx);
471}
size_t len
Definition apprentice.c:174
zval callback
Definition assert.c:25
void * lexbor_bst_remove_by_pointer(lexbor_bst_t *bst, lexbor_bst_entry_t *entry, lexbor_bst_entry_t **root)
Definition bst.c:287
void lexbor_bst_serialize_entry(lexbor_bst_entry_t *entry, lexbor_callback_f callback, void *ctx, size_t tabs)
Definition bst.c:414
lexbor_bst_t * lexbor_bst_create(void)
Definition bst.c:12
lxb_status_t lexbor_bst_init(lexbor_bst_t *bst, size_t size)
Definition bst.c:18
void lexbor_bst_serialize(lexbor_bst_t *bst, lexbor_callback_f callback, void *ctx)
Definition bst.c:408
lexbor_bst_entry_t * lexbor_bst_entry_make(lexbor_bst_t *bst, size_t size)
Definition bst.c:71
void * lexbor_bst_remove(lexbor_bst_t *bst, lexbor_bst_entry_t **scope, size_t size)
Definition bst.c:228
void * lexbor_bst_remove_close(lexbor_bst_t *bst, lexbor_bst_entry_t **scope, size_t size, size_t *found_size)
Definition bst.c:248
lexbor_bst_entry_t * lexbor_bst_insert(lexbor_bst_t *bst, lexbor_bst_entry_t **scope, size_t size, void *value)
Definition bst.c:86
lexbor_bst_entry_t * lexbor_bst_search(lexbor_bst_t *bst, lexbor_bst_entry_t *scope, size_t size)
Definition bst.c:188
lexbor_bst_t * lexbor_bst_destroy(lexbor_bst_t *bst, bool self_destroy)
Definition bst.c:55
void lexbor_bst_clean(lexbor_bst_t *bst)
Definition bst.c:44
lexbor_bst_entry_t * lexbor_bst_insert_not_exists(lexbor_bst_t *bst, lexbor_bst_entry_t **scope, size_t size)
Definition bst.c:145
lexbor_bst_entry_t * lexbor_bst_search_close(lexbor_bst_t *bst, lexbor_bst_entry_t *scope, size_t size)
Definition bst.c:206
struct lexbor_bst lexbor_bst_t
Definition bst.h:25
struct lexbor_bst_entry lexbor_bst_entry_t
Definition bst.h:24
size_t lexbor_conv_int64_to_data(int64_t num, lxb_char_t *buf, size_t len)
Definition conv.c:28
@ LXB_STATUS_ERROR_OBJECT_IS_NULL
Definition base.h:52
@ LXB_STATUS_ERROR_WRONG_ARGS
Definition base.h:58
@ LXB_STATUS_OK
Definition base.h:49
DNS_STATUS status
Definition dns_win32.c:49
void * lexbor_dobject_calloc(lexbor_dobject_t *dobject)
Definition dobject.c:123
lxb_status_t lexbor_dobject_init(lexbor_dobject_t *dobject, size_t chunk_size, size_t struct_size)
Definition dobject.c:22
void lexbor_dobject_clean(lexbor_dobject_t *dobject)
Definition dobject.c:64
lexbor_dobject_t * lexbor_dobject_destroy(lexbor_dobject_t *dobject, bool destroy_self)
Definition dobject.c:75
void * lexbor_dobject_free(lexbor_dobject_t *dobject, void *data)
Definition dobject.c:135
lexbor_dobject_t * lexbor_dobject_create(void)
Definition dobject.c:16
#define max(a, b)
Definition exif.c:60
new_type size
Definition ffi.c:4365
memcpy(ptr1, ptr2, size)
#define NULL
Definition gdcache.h:45
LXB_API void * lexbor_free(void *dst)
Definition memory.c:33
LXB_API void * lexbor_calloc(size_t num, size_t size)
Definition memory.c:27
lu_byte right
Definition minilua.c:4267
lu_byte left
Definition minilua.c:4266
#define next(ls)
Definition minilua.c:2661
void * value
Definition bst.h:31
lexbor_bst_entry_t * parent
Definition bst.h:36
lexbor_bst_entry_t * right
Definition bst.h:33
lexbor_bst_entry_t * left
Definition bst.h:34
lexbor_bst_entry_t * next
Definition bst.h:35
size_t size
Definition bst.h:38
size_t tree_length
Definition bst.h:45
lexbor_dobject_t * dobject
Definition bst.h:42
lexbor_bst_entry_t * root
Definition bst.h:43
unsigned int lxb_status_t
Definition types.h:28
unsigned char lxb_char_t
Definition types.h:27
lxb_status_t(* lexbor_callback_f)(const lxb_char_t *buffer, size_t size, void *ctx)
Definition types.h:31
value
new_op_array scope