From ad7807b972ce822bea28bba529bce25fa3af38d3 Mon Sep 17 00:00:00 2001 From: Quinton Miller Date: Sat, 1 Apr 2023 03:03:07 +0800 Subject: [PATCH 1/8] Refactor code for `Deque` buffer resizing --- src/deque.cr | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/deque.cr b/src/deque.cr index 938f60d993af..e677e379811b 100644 --- a/src/deque.cr +++ b/src/deque.cr @@ -363,7 +363,7 @@ class Deque(T) return unshift(value) if index == 0 return push(value) if index == @size - increase_capacity if @size >= @capacity + resize_if_cant_insert rindex = @start + index rindex -= @capacity if rindex >= @capacity @@ -474,7 +474,7 @@ class Deque(T) # a.push 3 # => Deque{1, 2, 3} # ``` def push(value : T) - increase_capacity if @size >= @capacity + resize_if_cant_insert index = @start + @size index -= @capacity if index >= @capacity @buffer[index] = value @@ -556,7 +556,7 @@ class Deque(T) # a.unshift 0 # => Deque{0, 1, 2} # ``` def unshift(value : T) : self - increase_capacity if @size >= @capacity + resize_if_cant_insert @start -= 1 @start += @capacity if @start < 0 @buffer[@start] = value @@ -581,15 +581,32 @@ class Deque(T) end end - private def increase_capacity + private INITIAL_CAPACITY = 4 + + private def calculate_new_capacity(new_size) + new_capacity = @capacity == 0 ? INITIAL_CAPACITY : @capacity + while new_capacity < new_size + new_capacity *= 2 + end + new_capacity + end + + private def resize_if_cant_insert(insert_size = 1) + new_capacity = calculate_new_capacity(@size + insert_size) + if new_capacity > @capacity + resize_to_capacity(new_capacity) + end + end + + private def resize_to_capacity(capacity) unless @buffer - @capacity = 4 + @capacity = capacity @buffer = Pointer(T).malloc(@capacity) return end old_capacity = @capacity - @capacity *= 2 + @capacity = capacity @buffer = @buffer.realloc(@capacity) finish = @start + @size From 4c1ffb9df7ea873ec6db9a84e97edcd4dd347bdb Mon Sep 17 00:00:00 2001 From: Quinton Miller Date: Sat, 1 Apr 2023 06:02:43 +0800 Subject: [PATCH 2/8] split overloads --- src/deque.cr | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/deque.cr b/src/deque.cr index e677e379811b..892e85989e42 100644 --- a/src/deque.cr +++ b/src/deque.cr @@ -583,6 +583,13 @@ class Deque(T) private INITIAL_CAPACITY = 4 + # behaves like `calculate_new_capacity(@capacity + 1)` + private def calculate_new_capacity + return INITIAL_CAPACITY if @capacity == 0 + + @capacity * 2 + end + private def calculate_new_capacity(new_size) new_capacity = @capacity == 0 ? INITIAL_CAPACITY : @capacity while new_capacity < new_size From ee6bd61e602c449691130fd2ac9567303fa386d9 Mon Sep 17 00:00:00 2001 From: Quinton Miller Date: Wed, 5 Apr 2023 04:47:10 +0800 Subject: [PATCH 3/8] fixup --- src/deque.cr | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/deque.cr b/src/deque.cr index 892e85989e42..327727f62c6f 100644 --- a/src/deque.cr +++ b/src/deque.cr @@ -606,14 +606,13 @@ class Deque(T) end private def resize_to_capacity(capacity) + old_capacity, @capacity = @capacity, capacity + unless @buffer - @capacity = capacity @buffer = Pointer(T).malloc(@capacity) return end - old_capacity = @capacity - @capacity = capacity @buffer = @buffer.realloc(@capacity) finish = @start + @size From ab2236748f7cfce4bec7def54d14094a505acd9b Mon Sep 17 00:00:00 2001 From: Quinton Miller Date: Wed, 5 Apr 2023 05:14:34 +0800 Subject: [PATCH 4/8] split `#resize_if_cant_insert` --- src/deque.cr | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/deque.cr b/src/deque.cr index 327727f62c6f..62a716d7c413 100644 --- a/src/deque.cr +++ b/src/deque.cr @@ -598,7 +598,14 @@ class Deque(T) new_capacity end - private def resize_if_cant_insert(insert_size = 1) + private def resize_if_cant_insert + new_capacity = calculate_new_capacity + if new_capacity > @capacity + resize_to_capacity(new_capacity) + end + end + + private def resize_if_cant_insert(insert_size) new_capacity = calculate_new_capacity(@size + insert_size) if new_capacity > @capacity resize_to_capacity(new_capacity) From 168be63b99811594d2c644253ba8bbdd1ccb3cde Mon Sep 17 00:00:00 2001 From: Quinton Miller Date: Wed, 5 Apr 2023 05:15:19 +0800 Subject: [PATCH 5/8] drop --- src/deque.cr | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/deque.cr b/src/deque.cr index 62a716d7c413..5342c7aa9287 100644 --- a/src/deque.cr +++ b/src/deque.cr @@ -605,13 +605,6 @@ class Deque(T) end end - private def resize_if_cant_insert(insert_size) - new_capacity = calculate_new_capacity(@size + insert_size) - if new_capacity > @capacity - resize_to_capacity(new_capacity) - end - end - private def resize_to_capacity(capacity) old_capacity, @capacity = @capacity, capacity From e95b3711fede45ba7f95720a1e6631077ac76236 Mon Sep 17 00:00:00 2001 From: Quinton Miller Date: Wed, 5 Apr 2023 05:15:42 +0800 Subject: [PATCH 6/8] drop2 --- src/deque.cr | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/deque.cr b/src/deque.cr index 5342c7aa9287..3c859150254d 100644 --- a/src/deque.cr +++ b/src/deque.cr @@ -590,14 +590,6 @@ class Deque(T) @capacity * 2 end - private def calculate_new_capacity(new_size) - new_capacity = @capacity == 0 ? INITIAL_CAPACITY : @capacity - while new_capacity < new_size - new_capacity *= 2 - end - new_capacity - end - private def resize_if_cant_insert new_capacity = calculate_new_capacity if new_capacity > @capacity From 8e20bb4805555ad2429163587a962a64e8865da9 Mon Sep 17 00:00:00 2001 From: Quinton Miller Date: Wed, 5 Apr 2023 06:00:49 +0800 Subject: [PATCH 7/8] fixup2 --- src/deque.cr | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/deque.cr b/src/deque.cr index 3c859150254d..1ed21ed93ddd 100644 --- a/src/deque.cr +++ b/src/deque.cr @@ -590,9 +590,11 @@ class Deque(T) @capacity * 2 end + # behaves like `resize_if_cant_insert(1)` private def resize_if_cant_insert new_capacity = calculate_new_capacity - if new_capacity > @capacity + # `>=` instead of `>` to ensure there is room for one element + if new_capacity >= @capacity resize_to_capacity(new_capacity) end end From 8ccbc5e46e98b6d3d114493e7b871414dd934fd6 Mon Sep 17 00:00:00 2001 From: Quinton Miller Date: Wed, 5 Apr 2023 06:18:59 +0800 Subject: [PATCH 8/8] nope --- src/deque.cr | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/deque.cr b/src/deque.cr index 1ed21ed93ddd..fc6cbf9a9785 100644 --- a/src/deque.cr +++ b/src/deque.cr @@ -592,10 +592,8 @@ class Deque(T) # behaves like `resize_if_cant_insert(1)` private def resize_if_cant_insert - new_capacity = calculate_new_capacity - # `>=` instead of `>` to ensure there is room for one element - if new_capacity >= @capacity - resize_to_capacity(new_capacity) + if @size >= @capacity + resize_to_capacity(calculate_new_capacity) end end