Skip to content

Commit 7439f28

Browse files
committed
Resizing done
1 parent 5cc36e1 commit 7439f28

File tree

1 file changed

+26
-14
lines changed

1 file changed

+26
-14
lines changed

src/Data/Deque/Mutable/Linear.hs

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77

88
-- | Mutable Linear Deque
99
--
10-
-- This module provides a pure interface to a bounded mutable deque.
11-
-- The deque has a maxiumum size and is represented with an array underneath.
10+
-- This module provides a pure interface to a mutable deque.
1211
--
1312
-- It is designed to be imported qualfied:
1413
--
@@ -22,7 +21,6 @@ module Data.Deque.Mutable.Linear
2221
-- * Querying
2322
, size
2423
, length
25-
, isFull
2624
, peekFront
2725
, peekBack
2826
-- * Modification
@@ -40,7 +38,6 @@ import qualified Data.Array.Mutable.Linear as Array
4038
import Data.Unrestricted.Linear
4139
import Prelude.Linear hiding (length, map)
4240
import qualified Prelude
43-
import GHC.Stack
4441

4542

4643
-- # Types
@@ -90,14 +87,14 @@ nextPtr sz (Ptr p) = (p + 1) `mod` sz
9087
-------------------------------------------------------------------------------
9188

9289
-- | Run a computation of an empty Deque with a given size
93-
alloc :: HasCallStack => Int -> (Deque a %1-> Ur b) %1-> Ur b
90+
alloc :: Int -> (Deque a %1-> Ur b) %1-> Ur b
9491
alloc k f = Array.alloc k err $ \arr -> f (Deque 0 0 arr) where
9592
err = Prelude.error "Accessing error element of a collection!"
9693

9794
-- | Run a computation on a Deque that is deterimined by the given the list
9895
-- where we treat the start and end of the list as the left and right pointers,
9996
-- with the total capacity as the length of the list.
100-
fromList :: HasCallStack => [a] -> (Deque a %1-> Ur b) %1-> Ur b
97+
fromList :: [a] -> (Deque a %1-> Ur b) %1-> Ur b
10198
fromList xs f =
10299
Array.fromList xs $ \arr -> f (Deque (Prelude.length xs) 0 arr)
103100

@@ -119,7 +116,7 @@ isFull :: Deque a %1-> (Ur Bool, Deque a)
119116
isFull d =
120117
size d & \(Ur sz, Deque len ptr arr) -> (Ur (len == sz), Deque len ptr arr)
121118

122-
peek :: HasCallStack => Face -> Deque a %1-> (Ur (Maybe a), Deque a)
119+
peek :: Face -> Deque a %1-> (Ur (Maybe a), Deque a)
123120
peek _ (Deque 0 p arr) = (Ur Nothing, Deque 0 p arr)
124121
peek face (Deque len ptr@(Ptr p) arr) = case face of
125122
Front ->
@@ -129,20 +126,20 @@ peek face (Deque len ptr@(Ptr p) arr) = case face of
129126
(Ur (Just a), Deque len ptr arr1)
130127

131128
-- | View the top of the left queue
132-
peekFront :: HasCallStack => Deque a %1-> (Ur (Maybe a), Deque a)
129+
peekFront :: Deque a %1-> (Ur (Maybe a), Deque a)
133130
peekFront = peek Front
134131

135132
-- | View the top of the right queue
136-
peekBack :: HasCallStack => Deque a %1-> (Ur (Maybe a), Deque a)
133+
peekBack :: Deque a %1-> (Ur (Maybe a), Deque a)
137134
peekBack = peek Back
138135

139136

140137
-- # Modification
141138
-------------------------------------------------------------------------------
142139

143-
push :: HasCallStack => Face -> a -> Deque a %1-> Deque a
140+
push :: Face -> a -> Deque a %1-> Deque a
144141
push face x deq = isFull deq & \case
145-
(Ur True, deq0) -> error "Pushing to full deque" $ deq0
142+
(Ur True, deq0) -> push face x (doubleSize deq0)
146143
(Ur False, Deque 0 _ arr) -> Array.write arr 0 x & \arr0 -> Deque 1 0 arr0
147144
(Ur False, Deque len (Ptr p) arr) -> case face of
148145
Front -> Array.size arr & \(Ur sz, arr0) ->
@@ -152,15 +149,28 @@ push face x deq = isFull deq & \case
152149
Array.write arr0 (backPtr 1 len sz (Ptr p)) x & \arr1 ->
153150
Deque (len+1) (Ptr p) arr1
154151

152+
doubleSize :: Deque a %1-> Deque a
153+
doubleSize (Deque len ptr@(Ptr start) arr) =
154+
Array.size arr & \(Ur sz, arr0) ->
155+
Array.resize (sz*2) err arr0 & \arr1 ->
156+
Deque len ptr (movePrefix 0 start arr1)
157+
where
158+
err = Prelude.error "Accessing error element of a collection!"
159+
movePrefix :: Int -> Int -> Array.Array a %1-> Array.Array a
160+
movePrefix ix p arr'
161+
| ix == p = arr'
162+
| otherwise = Array.read arr' ix & \(Ur a, arr0) ->
163+
Array.write arr0 (p+ix+1) a & \arr1 -> movePrefix (ix+1) p arr1
164+
155165
-- | Push to the front end
156-
pushFront :: HasCallStack => a -> Deque a %1-> Deque a
166+
pushFront :: a -> Deque a %1-> Deque a
157167
pushFront = push Front
158168

159169
-- | Push to the back end
160-
pushBack :: HasCallStack => a -> Deque a %1-> Deque a
170+
pushBack :: a -> Deque a %1-> Deque a
161171
pushBack = push Back
162172

163-
pop :: HasCallStack => Face -> Deque a %1-> (Ur (Maybe a), Deque a)
173+
pop :: Face -> Deque a %1-> (Ur (Maybe a), Deque a)
164174
pop _ (Deque 0 p arr) = (Ur Nothing, Deque 0 p arr)
165175
pop face (Deque len ptr@(Ptr p) arr) = case face of
166176
Front -> Array.size arr & \(Ur sz, arr0) ->
@@ -181,6 +191,8 @@ popBack = pop Back
181191
-- Note: We can't use a Prelude.Functor nor a Data.Functor
182192
-- because the mapped function need not be linear but we must
183193
-- consume the Deque linearly. The types don't align.
194+
-- Note: This could be more efficient if we only mapped the
195+
-- elements we care about and coerced the rest
184196
map :: (a -> b) -> Deque a %1-> Deque b
185197
map f (Deque len p arr) = Deque len p (Array.map f arr)
186198

0 commit comments

Comments
 (0)