Skip to content

Commit 3860cd1

Browse files
authored
Merge pull request #18 from metrix-ai/master
Optimize peekTQueue and peekTBQueue
2 parents b3e299c + 2636e45 commit 3860cd1

File tree

2 files changed

+28
-8
lines changed

2 files changed

+28
-8
lines changed

Control/Concurrent/STM/TBQueue.hs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,20 @@ flushTBQueue (TBQueue rsize read wsize write size) = do
161161
-- | Get the next value from the @TBQueue@ without removing it,
162162
-- retrying if the channel is empty.
163163
peekTBQueue :: TBQueue a -> STM a
164-
peekTBQueue c = do
165-
x <- readTBQueue c
166-
unGetTBQueue c x
167-
return x
164+
peekTBQueue (TBQueue _ read _ write _) = do
165+
xs <- readTVar read
166+
case xs of
167+
(x:_) -> return x
168+
[] -> do
169+
ys <- readTVar write
170+
case ys of
171+
[] -> retry
172+
_ -> do
173+
let (z:zs) = reverse ys -- NB. lazy: we want the transaction to be
174+
-- short, otherwise it will conflict
175+
writeTVar write []
176+
writeTVar read (z:zs)
177+
return z
168178

169179
-- | A version of 'peekTBQueue' which does not retry. Instead it
170180
-- returns @Nothing@ if no value is available.

Control/Concurrent/STM/TQueue.hs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,20 @@ flushTQueue (TQueue read write) = do
122122
-- | Get the next value from the @TQueue@ without removing it,
123123
-- retrying if the channel is empty.
124124
peekTQueue :: TQueue a -> STM a
125-
peekTQueue c = do
126-
x <- readTQueue c
127-
unGetTQueue c x
128-
return x
125+
peekTQueue (TQueue read write) = do
126+
xs <- readTVar read
127+
case xs of
128+
(x:_) -> return x
129+
[] -> do
130+
ys <- readTVar write
131+
case ys of
132+
[] -> retry
133+
_ -> do
134+
let (z:zs) = reverse ys -- NB. lazy: we want the transaction to be
135+
-- short, otherwise it will conflict
136+
writeTVar write []
137+
writeTVar read (z:zs)
138+
return z
129139

130140
-- | A version of 'peekTQueue' which does not retry. Instead it
131141
-- returns @Nothing@ if no value is available.

0 commit comments

Comments
 (0)