aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTucker Evans <tucker@tuckerevans.com>2021-01-03 17:00:20 -0500
committerTucker Evans <tucker@tuckerevans.com>2021-01-03 17:02:13 -0500
commit18020f74d43758be53351a05129f771099257c6b (patch)
tree53f5b49e5063b8c2152635ea112c12fac4cbba4e
parentdb396e6ede3b36ca1887450d8959de35b38d1ea7 (diff)
Add split function for ropes
Ropes should be rebalanced at the end of this function once rope_rebalance() is implemented.
-rw-r--r--structures/rope/rope.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/structures/rope/rope.c b/structures/rope/rope.c
index 1f0a389..6e79b24 100644
--- a/structures/rope/rope.c
+++ b/structures/rope/rope.c
@@ -131,3 +131,68 @@ rope *node1, *node2;
return tmp;
}
+
+rope* rope_split(root, i)
+rope **root;
+size_t i;
+{
+ rope **tmp, *split, *cur;
+
+ rope *orig = *root;
+
+ if (!root )
+ return NULL;
+
+ if (!i) {
+ split = *root;
+ *root = NULL;
+ return split;
+ }
+
+
+ tmp = root;
+ printf("i: %d\n", i);
+ while (!(*tmp)->str) {
+ if ((*tmp)->len <= i && (*tmp)->right) {
+ i -= (*tmp)->len;
+ printf("i: %d\n", i);
+ tmp = &(*tmp)->right;
+ } else if ((*tmp)->left) {
+ tmp = &(*tmp)->left;
+ }
+ }
+
+ if (i != 0) {
+ split = str_to_rope((*tmp)->str + i);
+ (*tmp)->str[i] = '\0';
+ /*Maybe want to strdup this and free to reduce memory usage*/
+
+ cur = (*tmp)->parent;
+ *tmp = rope_concat(*tmp, split);
+ (*tmp)->parent = cur;
+
+ split = (*tmp)->right;
+ (*tmp)->right = NULL;
+ } else {
+ split = *tmp;
+ }
+
+
+ for(cur = split; cur->parent; cur = cur->parent) {
+ if (cur->parent->right == cur)
+ continue;
+
+ split = rope_concat(split, cur->parent->right);
+ cur->parent->right = NULL;
+ }
+
+ if (cur && cur->right == split)
+ cur->right = NULL;
+ *root = cur;
+
+ /*TODO should be rebalancing rather than just recalulating lengths*/
+ rope_relen(split);
+ rope_relen(*root);
+
+ return split;
+}