@@ -22,6 +22,7 @@ module Cardano.DbSync.Cache (
22
22
queryStakeAddrWithCache ,
23
23
queryTxIdWithCache ,
24
24
rollbackCache ,
25
+ optimiseCaches ,
25
26
tryUpdateCacheTx ,
26
27
27
28
-- * CacheStatistics
@@ -80,6 +81,26 @@ rollbackCache (ActiveCache cache) blockId = do
80
81
atomically $ modifyTVar (cTxIds cache) FIFO. cleanupCache
81
82
void $ rollbackMapEpochInCache cache blockId
82
83
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
+
83
104
getCacheStatistics :: CacheStatus -> IO CacheStatistics
84
105
getCacheStatistics cs =
85
106
case cs of
@@ -150,34 +171,36 @@ queryStakeAddrWithCacheRetBs ::
150
171
queryStakeAddrWithCacheRetBs _trce cache cacheUA ra@ (Ledger. RewardAccount _ cred) = do
151
172
let bs = Ledger. serialiseRewardAccount ra
152
173
case cache of
153
- NoCache -> do
154
- mapLeft (,bs) <$> resolveStakeAddress bs
174
+ NoCache -> rsStkAdrrs bs
155
175
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
181
204
182
205
-- | True if it was found in LRU
183
206
queryStakeCache :: StakeCred -> StakeCache -> Maybe (DB. StakeAddressId , StakeCache )
@@ -306,26 +329,29 @@ queryMAWithCache ::
306
329
ReaderT SqlBackend m (Either (ByteString , ByteString ) DB. MultiAssetId )
307
330
queryMAWithCache cache policyId asset =
308
331
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
310
352
let ! policyBs = Generic. unScriptHash $ policyID policyId
311
353
let ! assetNameBs = Generic. unAssetName asset
312
354
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
329
355
330
356
queryPrevBlockWithCache ::
331
357
MonadIO m =>
@@ -364,42 +390,42 @@ queryTxIdWithCache ::
364
390
queryTxIdWithCache cache txIdLedger = do
365
391
case cache of
366
392
-- 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
389
416
where
390
417
txHash = Generic. unTxHash txIdLedger
418
+ qTxHash = DB. queryTxId txHash
391
419
392
420
tryUpdateCacheTx ::
393
421
MonadIO m =>
394
422
CacheStatus ->
395
423
Ledger. TxId StandardCrypto ->
396
424
DB. TxId ->
397
425
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 ()
403
429
404
430
insertBlockAndCache ::
405
431
(MonadIO m , MonadBaseControl IO m ) =>
@@ -408,13 +434,16 @@ insertBlockAndCache ::
408
434
ReaderT SqlBackend m DB. BlockId
409
435
insertBlockAndCache cache block =
410
436
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
418
447
419
448
queryDatum ::
420
449
MonadIO m =>
@@ -423,18 +452,21 @@ queryDatum ::
423
452
ReaderT SqlBackend m (Maybe DB. DatumId )
424
453
queryDatum cache hsh = do
425
454
case cache of
426
- NoCache -> DB. queryDatum $ Generic. dataHashToBytes hsh
455
+ NoCache -> queryDtm
427
456
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
438
470
439
471
-- This assumes the entry is not cached.
440
472
insertDatumAndCache ::
@@ -447,12 +479,25 @@ insertDatumAndCache cache hsh dt = do
447
479
datumId <- DB. insertDatum dt
448
480
case cache of
449
481
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
456
501
457
502
-- Stakes
458
503
hitCreds :: StrictTVar IO CacheStatistics -> IO ()
0 commit comments