Split 'node' into two parts, parameterized by 'offset' and 'after'. * * The 'after' argument controls which quicklistNode gets returned. * If 'after'==1, returned node has elements after 'offset'. * input node keeps elements up to 'offset', including 'offset'. * If 'after'==0, returned node has elements up to 'offset'. * input node keeps elements after 'offset',
| 818 | * |
| 819 | * Returns newly created node or NULL if split not possible. */ |
| 820 | REDIS_STATIC quicklistNode *_quicklistSplitNode(quicklistNode *node, int offset, |
| 821 | int after) { |
| 822 | size_t zl_sz = node->sz; |
| 823 | |
| 824 | quicklistNode *new_node = quicklistCreateNode(); |
| 825 | new_node->zl = zmalloc(zl_sz); |
| 826 | |
| 827 | /* Copy original ziplist so we can split it */ |
| 828 | memcpy(new_node->zl, node->zl, zl_sz); |
| 829 | |
| 830 | /* Ranges to be trimmed: -1 here means "continue deleting until the list ends" */ |
| 831 | int orig_start = after ? offset + 1 : 0; |
| 832 | int orig_extent = after ? -1 : offset; |
| 833 | int new_start = after ? 0 : offset; |
| 834 | int new_extent = after ? offset + 1 : -1; |
| 835 | |
| 836 | D("After %d (%d); ranges: [%d, %d], [%d, %d]", after, offset, orig_start, |
| 837 | orig_extent, new_start, new_extent); |
| 838 | |
| 839 | node->zl = ziplistDeleteRange(node->zl, orig_start, orig_extent); |
| 840 | node->count = ziplistLen(node->zl); |
| 841 | quicklistNodeUpdateSz(node); |
| 842 | |
| 843 | new_node->zl = ziplistDeleteRange(new_node->zl, new_start, new_extent); |
| 844 | new_node->count = ziplistLen(new_node->zl); |
| 845 | quicklistNodeUpdateSz(new_node); |
| 846 | |
| 847 | D("After split lengths: orig (%d), new (%d)", node->count, new_node->count); |
| 848 | return new_node; |
| 849 | } |
| 850 | |
| 851 | /* Insert a new entry before or after existing entry 'entry'. |
| 852 | * |
no test coverage detected