Return the next node or data pointer in the defragmentation walk. * Return 1 if a new item was returned, 0 if the scan is finished or if * an out of memory error happened while extending the iterator state. * * The walk is preorder over the real nodes of the radix tree. Every node is * returned first as a NODE item. If the node also represents a key with * non-NULL associated data, the same
| 2434 | * Inline leaves are returned only as DATA items, since there is no standalone |
| 2435 | * node allocation to relocate for them. */ |
| 2436 | int raxDefragNext(raxDefragIterator *it) { |
| 2437 | raxDefragFrame *frame; |
| 2438 | |
| 2439 | if (it->eof) return 0; |
| 2440 | if (it->pending_todel) { |
| 2441 | raxDefragDelChars(it,it->pending_todel); |
| 2442 | it->pending_todel = 0; |
| 2443 | } |
| 2444 | |
| 2445 | while((frame = raxDefragStackPeek(it)) != NULL) { |
| 2446 | raxNode *node = frame->node; |
| 2447 | int numchildren = node->iscompr ? 1 : node->size; |
| 2448 | |
| 2449 | if (frame->state == RAX_DEFRAG_STATE_EMIT_NODE) { |
| 2450 | frame->state = RAX_DEFRAG_STATE_EMIT_DATA; |
| 2451 | it->kind = RAX_DEFRAG_NODE; |
| 2452 | it->flags = raxDefragNodeFlags(it,node); |
| 2453 | it->size = raxNodeCurrentLength(node); |
| 2454 | it->ptr = node; |
| 2455 | it->node = node; |
| 2456 | it->node_child = frame->parent_child; |
| 2457 | return 1; |
| 2458 | } else if (frame->state == RAX_DEFRAG_STATE_EMIT_DATA) { |
| 2459 | frame->state = RAX_DEFRAG_STATE_CHILDREN; |
| 2460 | if (node->iskey && !node->isnull) { |
| 2461 | it->kind = RAX_DEFRAG_DATA; |
| 2462 | it->flags = raxDefragNodeFlags(it,node); |
| 2463 | it->size = 0; |
| 2464 | it->ptr = raxGetData(node); |
| 2465 | it->node = node; |
| 2466 | it->node_child = frame->parent_child; |
| 2467 | return 1; |
| 2468 | } |
| 2469 | } else { |
| 2470 | if (frame->child == (size_t)numchildren) { |
| 2471 | raxDefragStackPop(it); |
| 2472 | if (it->items == 0) { |
| 2473 | it->eof = 1; |
| 2474 | return 0; |
| 2475 | } |
| 2476 | raxNode *parent = raxDefragStackPeek(it)->node; |
| 2477 | raxDefragDelChars(it,parent->iscompr ? parent->size : 1); |
| 2478 | continue; |
| 2479 | } |
| 2480 | |
| 2481 | int childidx = frame->child++; |
| 2482 | raxNode **childfield = raxNodeFirstChildPtr(node)+childidx; |
| 2483 | size_t addlen = node->iscompr ? node->size : 1; |
| 2484 | unsigned char *s = node->iscompr ? node->data : node->data+childidx; |
| 2485 | |
| 2486 | if (raxIsInlineLeaf(node,childidx)) { |
| 2487 | void *value; |
| 2488 | memcpy(&value,childfield,sizeof(value)); |
| 2489 | if (value == NULL) continue; |
| 2490 | if (!raxDefragAddChars(it,s,addlen)) return 0; |
| 2491 | it->pending_todel = addlen; |
| 2492 | it->kind = RAX_DEFRAG_DATA; |
| 2493 | it->flags = RAX_DEFRAG_F_KEY|RAX_DEFRAG_F_INLINE_DATA| |
nothing calls this directly
no test coverage detected