@@ -22,6 +22,7 @@ module Cardano.DbSync.Cache (
2222 queryStakeAddrWithCache ,
2323 queryTxIdWithCache ,
2424 rollbackCache ,
25+ optimiseCaches ,
2526 tryUpdateCacheTx ,
2627
2728 -- * CacheStatistics
@@ -80,6 +81,26 @@ rollbackCache (ActiveCache cache) blockId = do
8081 atomically $ modifyTVar (cTxIds cache) FIFO. cleanupCache
8182 void $ rollbackMapEpochInCache cache blockId
8283
84+ -- | When syncing and we get within 2 minutes of the tip, we can optimise the caches
85+ -- and set the flag to True on ActiveCache.leaving the following caches as they are:
86+ -- cPools, cPrevBlock, Cstats, cEpoch
87+ optimiseCaches :: MonadIO m => CacheStatus -> ReaderT SqlBackend m ()
88+ optimiseCaches cache =
89+ case cache of
90+ NoCache -> pure ()
91+ ActiveCache c ->
92+ withCacheOptimisationCheck c (pure () ) $
93+ liftIO $ do
94+ -- empty caches not to be used anymore
95+ atomically $ modifyTVar (cTxIds c) FIFO. cleanupCache
96+ atomically $ writeTVar (cStake c) (StakeCache Map. empty (LRU. empty 0 ))
97+ atomically $ modifyTVar (cDatum c) (LRU. optimise 0 )
98+ -- empty then limit the capacity of the cache
99+ atomically $ writeTVar (cMultiAssets c) (LRU. empty 50000 )
100+ -- set the flag to True
101+ atomically $ writeTVar (cIsCacheOptimised c) True
102+ pure ()
103+
83104getCacheStatistics :: CacheStatus -> IO CacheStatistics
84105getCacheStatistics cs =
85106 case cs of
@@ -150,34 +171,36 @@ queryStakeAddrWithCacheRetBs ::
150171queryStakeAddrWithCacheRetBs _trce cache cacheUA ra@ (Ledger. RewardAccount _ cred) = do
151172 let bs = Ledger. serialiseRewardAccount ra
152173 case cache of
153- NoCache -> do
154- mapLeft (,bs) <$> resolveStakeAddress bs
174+ NoCache -> rsStkAdrrs bs
155175 ActiveCache ci -> do
156- stakeCache <- liftIO $ readTVarIO (cStake ci)
157- case queryStakeCache cred stakeCache of
158- Just (addrId, stakeCache') -> do
159- liftIO $ hitCreds (cStats ci)
160- case cacheUA of
161- EvictAndUpdateCache -> do
162- liftIO $ atomically $ writeTVar (cStake ci) $ deleteStakeCache cred stakeCache'
163- pure $ Right addrId
164- _other -> do
165- liftIO $ atomically $ writeTVar (cStake ci) stakeCache'
166- pure $ Right addrId
167- Nothing -> do
168- queryRes <- mapLeft (,bs) <$> resolveStakeAddress bs
169- liftIO $ missCreds (cStats ci)
170- case queryRes of
171- Left _ -> pure queryRes
172- Right stakeAddrsId -> do
173- let ! stakeCache' = case cacheUA of
174- UpdateCache -> stakeCache {scLruCache = LRU. insert cred stakeAddrsId (scLruCache stakeCache)}
175- UpdateCacheStrong -> stakeCache {scStableCache = Map. insert cred stakeAddrsId (scStableCache stakeCache)}
176- _ -> stakeCache
177- liftIO $
178- atomically $
179- writeTVar (cStake ci) stakeCache'
180- pure $ Right stakeAddrsId
176+ withCacheOptimisationCheck ci (rsStkAdrrs bs) $ do
177+ stakeCache <- liftIO $ readTVarIO (cStake ci)
178+ case queryStakeCache cred stakeCache of
179+ Just (addrId, stakeCache') -> do
180+ liftIO $ hitCreds (cStats ci)
181+ case cacheUA of
182+ EvictAndUpdateCache -> do
183+ liftIO $ atomically $ writeTVar (cStake ci) $ deleteStakeCache cred stakeCache'
184+ pure $ Right addrId
185+ _other -> do
186+ liftIO $ atomically $ writeTVar (cStake ci) stakeCache'
187+ pure $ Right addrId
188+ Nothing -> do
189+ queryRes <- mapLeft (,bs) <$> resolveStakeAddress bs
190+ liftIO $ missCreds (cStats ci)
191+ case queryRes of
192+ Left _ -> pure queryRes
193+ Right stakeAddrsId -> do
194+ let ! stakeCache' = case cacheUA of
195+ UpdateCache -> stakeCache {scLruCache = LRU. insert cred stakeAddrsId (scLruCache stakeCache)}
196+ UpdateCacheStrong -> stakeCache {scStableCache = Map. insert cred stakeAddrsId (scStableCache stakeCache)}
197+ _otherwise -> stakeCache
198+ liftIO $
199+ atomically $
200+ writeTVar (cStake ci) stakeCache'
201+ pure $ Right stakeAddrsId
202+ where
203+ rsStkAdrrs bs = mapLeft (,bs) <$> resolveStakeAddress bs
181204
182205-- | True if it was found in LRU
183206queryStakeCache :: StakeCred -> StakeCache -> Maybe (DB. StakeAddressId , StakeCache )
@@ -306,26 +329,29 @@ queryMAWithCache ::
306329 ReaderT SqlBackend m (Either (ByteString , ByteString ) DB. MultiAssetId )
307330queryMAWithCache cache policyId asset =
308331 case cache of
309- NoCache -> do
332+ NoCache -> queryDb
333+ ActiveCache ci -> do
334+ withCacheOptimisationCheck ci queryDb $ do
335+ mp <- liftIO $ readTVarIO (cMultiAssets ci)
336+ case LRU. lookup (policyId, asset) mp of
337+ Just (maId, mp') -> do
338+ liftIO $ hitMAssets (cStats ci)
339+ liftIO $ atomically $ writeTVar (cMultiAssets ci) mp'
340+ pure $ Right maId
341+ Nothing -> do
342+ liftIO $ missMAssets (cStats ci)
343+ -- miss. The lookup doesn't change the cache on a miss.
344+ let ! policyBs = Generic. unScriptHash $ policyID policyId
345+ let ! assetNameBs = Generic. unAssetName asset
346+ maId <- maybe (Left (policyBs, assetNameBs)) Right <$> DB. queryMultiAssetId policyBs assetNameBs
347+ whenRight maId $
348+ liftIO . atomically . modifyTVar (cMultiAssets ci) . LRU. insert (policyId, asset)
349+ pure maId
350+ where
351+ queryDb = do
310352 let ! policyBs = Generic. unScriptHash $ policyID policyId
311353 let ! assetNameBs = Generic. unAssetName asset
312354 maybe (Left (policyBs, assetNameBs)) Right <$> DB. queryMultiAssetId policyBs assetNameBs
313- ActiveCache ci -> do
314- mp <- liftIO $ readTVarIO (cMultiAssets ci)
315- case LRU. lookup (policyId, asset) mp of
316- Just (maId, mp') -> do
317- liftIO $ hitMAssets (cStats ci)
318- liftIO $ atomically $ writeTVar (cMultiAssets ci) mp'
319- pure $ Right maId
320- Nothing -> do
321- liftIO $ missMAssets (cStats ci)
322- -- miss. The lookup doesn't change the cache on a miss.
323- let ! policyBs = Generic. unScriptHash $ policyID policyId
324- let ! assetNameBs = Generic. unAssetName asset
325- maId <- maybe (Left (policyBs, assetNameBs)) Right <$> DB. queryMultiAssetId policyBs assetNameBs
326- whenRight maId $
327- liftIO . atomically . modifyTVar (cMultiAssets ci) . LRU. insert (policyId, asset)
328- pure maId
329355
330356queryPrevBlockWithCache ::
331357 MonadIO m =>
@@ -364,42 +390,42 @@ queryTxIdWithCache ::
364390queryTxIdWithCache cache txIdLedger = do
365391 case cache of
366392 -- Direct database query if no cache.
367- NoCache -> DB. queryTxId txHash
368- ActiveCache cacheInternal -> do
369- -- Read current cache state.
370- cacheTx <- liftIO $ readTVarIO (cTxIds cacheInternal)
371-
372- case FIFO. lookup txIdLedger cacheTx of
373- -- Cache hit, return the transaction ID.
374- Just txId -> do
375- liftIO $ hitTxIds (cStats cacheInternal)
376- pure $ Right txId
377- -- Cache miss.
378- Nothing -> do
379- eTxId <- DB. queryTxId txHash
380- liftIO $ missTxIds (cStats cacheInternal)
381- case eTxId of
382- Right txId -> do
383- -- Update cache.
384- liftIO $ atomically $ modifyTVar (cTxIds cacheInternal) $ FIFO. insert txIdLedger txId
385- -- Return ID after updating cache.
386- pure $ Right txId
387- -- Return lookup failure.
388- Left _ -> pure $ Left $ DB. DbLookupTxHash txHash
393+ NoCache -> qTxHash
394+ ActiveCache ci ->
395+ withCacheOptimisationCheck ci qTxHash $ do
396+ -- Read current cache state.
397+ cacheTx <- liftIO $ readTVarIO (cTxIds ci)
398+
399+ case FIFO. lookup txIdLedger cacheTx of
400+ -- Cache hit, return the transaction ID.
401+ Just txId -> do
402+ liftIO $ hitTxIds (cStats ci)
403+ pure $ Right txId
404+ -- Cache miss.
405+ Nothing -> do
406+ eTxId <- qTxHash
407+ liftIO $ missTxIds (cStats ci)
408+ case eTxId of
409+ Right txId -> do
410+ -- Update cache.
411+ liftIO $ atomically $ modifyTVar (cTxIds ci) $ FIFO. insert txIdLedger txId
412+ -- Return ID after updating cache.
413+ pure $ Right txId
414+ -- Return lookup failure.
415+ Left _ -> pure $ Left $ DB. DbLookupTxHash txHash
389416 where
390417 txHash = Generic. unTxHash txIdLedger
418+ qTxHash = DB. queryTxId txHash
391419
392420tryUpdateCacheTx ::
393421 MonadIO m =>
394422 CacheStatus ->
395423 Ledger. TxId StandardCrypto ->
396424 DB. TxId ->
397425 m ()
398- tryUpdateCacheTx cache ledgerTxId txId = do
399- case cache of
400- NoCache -> pure ()
401- ActiveCache ci -> do
402- liftIO $ atomically $ modifyTVar (cTxIds ci) $ FIFO. insert ledgerTxId txId
426+ tryUpdateCacheTx (ActiveCache ci) ledgerTxId txId =
427+ liftIO $ atomically $ modifyTVar (cTxIds ci) $ FIFO. insert ledgerTxId txId
428+ tryUpdateCacheTx _ _ _ = pure ()
403429
404430insertBlockAndCache ::
405431 (MonadIO m , MonadBaseControl IO m ) =>
@@ -408,13 +434,16 @@ insertBlockAndCache ::
408434 ReaderT SqlBackend m DB. BlockId
409435insertBlockAndCache cache block =
410436 case cache of
411- NoCache -> DB. insertBlock block
412- ActiveCache ci -> do
413- bid <- DB. insertBlock block
414- liftIO $ do
415- missPrevBlock (cStats ci)
416- atomically $ writeTVar (cPrevBlock ci) $ Just (bid, DB. blockHash block)
417- pure bid
437+ NoCache -> insBlck
438+ ActiveCache ci ->
439+ withCacheOptimisationCheck ci insBlck $ do
440+ bid <- insBlck
441+ liftIO $ do
442+ missPrevBlock (cStats ci)
443+ atomically $ writeTVar (cPrevBlock ci) $ Just (bid, DB. blockHash block)
444+ pure bid
445+ where
446+ insBlck = DB. insertBlock block
418447
419448queryDatum ::
420449 MonadIO m =>
@@ -423,18 +452,21 @@ queryDatum ::
423452 ReaderT SqlBackend m (Maybe DB. DatumId )
424453queryDatum cache hsh = do
425454 case cache of
426- NoCache -> DB. queryDatum $ Generic. dataHashToBytes hsh
455+ NoCache -> queryDtm
427456 ActiveCache ci -> do
428- mp <- liftIO $ readTVarIO (cDatum ci)
429- case LRU. lookup hsh mp of
430- Just (datumId, mp') -> do
431- liftIO $ hitDatum (cStats ci)
432- liftIO $ atomically $ writeTVar (cDatum ci) mp'
433- pure $ Just datumId
434- Nothing -> do
435- liftIO $ missDatum (cStats ci)
436- -- miss. The lookup doesn't change the cache on a miss.
437- DB. queryDatum $ Generic. dataHashToBytes hsh
457+ withCacheOptimisationCheck ci queryDtm $ do
458+ mp <- liftIO $ readTVarIO (cDatum ci)
459+ case LRU. lookup hsh mp of
460+ Just (datumId, mp') -> do
461+ liftIO $ hitDatum (cStats ci)
462+ liftIO $ atomically $ writeTVar (cDatum ci) mp'
463+ pure $ Just datumId
464+ Nothing -> do
465+ liftIO $ missDatum (cStats ci)
466+ -- miss. The lookup doesn't change the cache on a miss.
467+ queryDtm
468+ where
469+ queryDtm = DB. queryDatum $ Generic. dataHashToBytes hsh
438470
439471-- This assumes the entry is not cached.
440472insertDatumAndCache ::
@@ -447,12 +479,25 @@ insertDatumAndCache cache hsh dt = do
447479 datumId <- DB. insertDatum dt
448480 case cache of
449481 NoCache -> pure datumId
450- ActiveCache ci -> do
451- liftIO $
452- atomically $
453- modifyTVar (cDatum ci) $
454- LRU. insert hsh datumId
455- pure datumId
482+ ActiveCache ci ->
483+ withCacheOptimisationCheck ci (pure datumId) $ do
484+ liftIO $
485+ atomically $
486+ modifyTVar (cDatum ci) $
487+ LRU. insert hsh datumId
488+ pure datumId
489+
490+ withCacheOptimisationCheck ::
491+ MonadIO m =>
492+ CacheInternal ->
493+ m a -> -- Action to perform if cache is optimised
494+ m a -> -- Action to perform if cache is not optimised
495+ m a
496+ withCacheOptimisationCheck ci ifOptimised ifNotOptimised = do
497+ isCachedOptimised <- liftIO $ readTVarIO (cIsCacheOptimised ci)
498+ if isCachedOptimised
499+ then ifOptimised
500+ else ifNotOptimised
456501
457502-- Stakes
458503hitCreds :: StrictTVar IO CacheStatistics -> IO ()
0 commit comments