Skip to content

Commit 0d8e598

Browse files
committed
Fixed Sieve.delete advancing finger unnecessarilly
1 parent b8f4834 commit 0d8e598

1 file changed

Lines changed: 46 additions & 37 deletions

File tree

src/PostgREST/Cache/Sieve.hs

Lines changed: 46 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,41 @@ import GHC.Conc (numCapabilities)
3030
import Protolude hiding (head)
3131
import qualified StmHamt.SizedHamt as SH
3232

33-
data Node = Node {
34-
getVisited :: STM Bool,
35-
visit :: STM (),
36-
clear :: STM (),
37-
remove :: STM (),
38-
next :: TVar Node,
39-
prev :: TVar Node
40-
}
33+
data Node = Head {
34+
next :: TVar Node,
35+
prev :: TVar Node
36+
} |
37+
Node {
38+
next :: TVar Node,
39+
prev :: TVar Node,
40+
visited :: TVar Bool
41+
} deriving Eq
42+
43+
getVisited :: Node -> STM Bool
44+
getVisited (Head _ _) = pure True
45+
getVisited Node{visited} = readTVar visited
46+
47+
visit :: Node -> STM ()
48+
visit (Head _ _) = pure ()
49+
visit Node{visited} = writeTVar visited True
50+
51+
clear :: Node -> STM ()
52+
clear (Head _ _) = pure ()
53+
clear Node{visited} = writeTVar visited False
54+
55+
remove :: Node -> STM ()
56+
remove (Head _ _) = pure ()
57+
remove Node{next=currNext, prev=currPrev} = do
58+
nextEntry <- readTVar currNext
59+
prevEntry <- readTVar currPrev
60+
writeTVar (next prevEntry) nextEntry
61+
writeTVar (prev nextEntry) prevEntry
4162

4263
data Entry k v = Entry {
4364
ekey :: k,
4465
value :: v,
4566
node :: Node
46-
}
67+
} deriving Eq
4768

4869
data Cache m k v =
4970
Cache {
@@ -76,11 +97,10 @@ cacheIO maxSize = atomically . cache maxSize
7697

7798
cache :: Hashable k => TVar Int -> (k -> m v) -> STM (Cache m k v)
7899
cache maxSize load = mdo
79-
let noop = pure ()
80-
advanceFinger = modifyTVarM fingerTVar (readTVar . next)
100+
let advanceFinger = modifyTVarM fingerTVar (readTVar . next)
81101
reset = SH.reset entries *> writeTVar fingerTVar head
82102
lookupAndVisit = traverse visitEntry <=< flip (SH.lookup ekey) entries
83-
head <- Node (pure True) noop advanceFinger advanceFinger <$> newTVar head <*> newTVar head
103+
head <- Head <$> newTVar head <*> newTVar head
84104
entries <- SH.new
85105
fingerTVar <- newTVar head
86106
cache <- Cache
@@ -101,7 +121,13 @@ cache maxSize load = mdo
101121
visitEntry Entry{node, value} = visit node $> value
102122

103123
delete :: Hashable k => Cache m k v -> k -> STM ()
104-
delete Cache{entries} k = whenJustM (SH.lookup ekey k entries) (remove . node)
124+
delete Cache{entries, getFinger, advanceFinger} k =
125+
whenJustM (SH.focus F.lookupAndDelete ekey k entries) (removeAndCheckFinger . node)
126+
where
127+
removeAndCheckFinger node = do
128+
remove node
129+
whenM ((node ==) <$> getFinger)
130+
advanceFinger
105131

106132
deleteIO :: Hashable k => Cache m k v -> k -> IO ()
107133
deleteIO c = atomically . delete c
@@ -157,15 +183,16 @@ cached Cache{..} k =
157183
if currDiff >= 0 then do
158184
-- no space in the cache
159185
-- need to evict an entry
160-
Node{getVisited, clear, remove} <- getFinger
161-
visited <- getVisited
186+
node <- getFinger
187+
visited <- getVisited node
162188
if visited then
163189
-- clear and skip visited entry
164190
-- not done yet
165-
clear $> empty
191+
clear node *> advanceFinger $> empty
166192
else do
167193
-- found entry to evict
168-
remove
194+
SH.focus F.delete ekey k entries
195+
remove node *> advanceFinger
169196
modifyTVar evictions (+ 1)
170197
if currDiff == 0 then
171198
-- now there is space
@@ -182,27 +209,9 @@ cached Cache{..} k =
182209

183210
addEntry v = do
184211
oldNeck <- readTVar $ prev head
185-
nextTVar <- newTVar head
186-
prevTVar <- newTVar oldNeck
187-
visitedTVar <- newTVar False
188-
let
189-
removeEntry = do
190-
nextEntry <- readTVar nextTVar
191-
prevEntry <- readTVar prevTVar
192-
writeTVar (next prevEntry) nextEntry
193-
writeTVar (prev nextEntry) prevEntry
194-
SH.focus F.delete ekey k entries
195-
newNeck = Node
196-
(readTVar visitedTVar)
197-
(writeTVar visitedTVar True)
198-
-- both clear and remove advance the finger
199-
(writeTVar visitedTVar False *> advanceFinger)
200-
(removeEntry *> advanceFinger)
201-
nextTVar
202-
prevTVar
203-
newEntry = Entry k v newNeck
212+
newNeck <- Node <$> newTVar head <*> newTVar oldNeck <*> newTVar False
204213
-- add cache entry
205-
SH.insert ekey newEntry entries
214+
SH.insert ekey (Entry k v newNeck) entries
206215
-- update pointers
207216
writeTVar (next oldNeck) newNeck
208217
writeTVar (prev head) newNeck

0 commit comments

Comments
 (0)