Skip to content

Commit 2318852

Browse files
committed
1906 - Add cache for address
1 parent d54c3f3 commit 2318852

File tree

7 files changed

+154
-126
lines changed

7 files changed

+154
-126
lines changed

cardano-db-sync/src/Cardano/DbSync/Api.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,8 @@ mkSyncEnv trce backend connectionString syncOptions protoInfo nw nwMagic systemS
353353
then
354354
newEmptyCache
355355
CacheCapacity
356-
{ cacheCapacityStake = 100000
356+
{ cacheCapacityAddress = 100000
357+
, cacheCapacityStake = 100000
357358
, cacheCapacityDatum = 250000
358359
, cacheCapacityMultiAsset = 250000
359360
, cacheCapacityTx = 100000

cardano-db-sync/src/Cardano/DbSync/Cache.hs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ module Cardano.DbSync.Cache (
1818
queryPrevBlockWithCache,
1919
queryOrInsertStakeAddress,
2020
queryOrInsertRewardAccount,
21+
insertAddressUsingCache,
2122
insertStakeAddress,
2223
queryStakeAddrWithCache,
2324
queryTxIdWithCache,
@@ -31,6 +32,7 @@ module Cardano.DbSync.Cache (
3132

3233
import Cardano.BM.Trace
3334
import qualified Cardano.Db as DB
35+
import qualified Cardano.Db.Schema.Variant.TxOut as V
3436
import Cardano.DbSync.Cache.Epoch (rollbackMapEpochInCache)
3537
import qualified Cardano.DbSync.Cache.FIFO as FIFO
3638
import qualified Cardano.DbSync.Cache.LRU as LRU
@@ -253,6 +255,52 @@ queryPoolKeyWithCache cache cacheUA hsh =
253255
Map.insert hsh phId
254256
pure $ Right phId
255257

258+
insertAddressUsingCache ::
259+
(MonadBaseControl IO m, MonadIO m) =>
260+
CacheStatus ->
261+
CacheAction ->
262+
ByteString ->
263+
V.Address ->
264+
ReaderT SqlBackend m V.AddressId
265+
insertAddressUsingCache cache cacheUA addrRaw vAdrs = do
266+
case cache of
267+
NoCache -> do
268+
mAddrId <- DB.queryAddressId addrRaw
269+
processResult mAddrId
270+
ActiveCache ci -> do
271+
adrs <- liftIO $ readTVarIO (cAddress ci)
272+
case LRU.lookup addrRaw adrs of
273+
Just (addrId, adrs') -> do
274+
liftIO $ hitAddress (cStats ci)
275+
liftIO $ atomically $ writeTVar (cAddress ci) adrs'
276+
pure addrId
277+
Nothing -> do
278+
liftIO $ missAddress (cStats ci)
279+
mAddrId <- DB.queryAddressId addrRaw
280+
processWithCache mAddrId ci
281+
where
282+
processResult mAddrId =
283+
case mAddrId of
284+
Nothing -> DB.insertAddress vAdrs
285+
Just addrId -> pure addrId
286+
287+
processWithCache mAddrId ci =
288+
case mAddrId of
289+
Nothing -> do
290+
addrId <- DB.insertAddress vAdrs
291+
cacheIfNeeded addrId ci
292+
pure addrId
293+
Just addrId -> do
294+
cacheIfNeeded addrId ci
295+
pure addrId
296+
297+
cacheIfNeeded addrId ci =
298+
when (shouldCache cacheUA) $
299+
liftIO $
300+
atomically $
301+
modifyTVar (cAddress ci) $
302+
LRU.insert addrRaw addrId
303+
256304
insertPoolKeyWithCache ::
257305
(MonadBaseControl IO m, MonadIO m) =>
258306
CacheStatus ->
@@ -535,6 +583,15 @@ missMAssets :: StrictTVar IO CacheStatistics -> IO ()
535583
missMAssets ref =
536584
atomically $ modifyTVar ref (\cs -> cs {multiAssetsQueries = 1 + multiAssetsQueries cs})
537585

586+
-- Address
587+
hitAddress :: StrictTVar IO CacheStatistics -> IO ()
588+
hitAddress ref =
589+
atomically $ modifyTVar ref (\cs -> cs {addressHits = 1 + addressHits cs, addressQueries = 1 + addressQueries cs})
590+
591+
missAddress :: StrictTVar IO CacheStatistics -> IO ()
592+
missAddress ref =
593+
atomically $ modifyTVar ref (\cs -> cs {addressQueries = 1 + addressQueries cs})
594+
538595
-- Blocks
539596
hitPBlock :: StrictTVar IO CacheStatistics -> IO ()
540597
hitPBlock ref =

cardano-db-sync/src/Cardano/DbSync/Cache/Types.hs

Lines changed: 76 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ module Cardano.DbSync.Cache.Types (
3131
) where
3232

3333
import qualified Cardano.Db as DB
34+
import qualified Cardano.Db.Schema.Variant.TxOut as V
3435
import Cardano.DbSync.Cache.FIFO (FIFOCache)
3536
import qualified Cardano.DbSync.Cache.FIFO as FIFO
3637
import Cardano.DbSync.Cache.LRU (LRUCache)
@@ -82,6 +83,7 @@ data CacheInternal = CacheInternal
8283
, cPrevBlock :: !(StrictTVar IO (Maybe (DB.BlockId, ByteString)))
8384
, cStats :: !(StrictTVar IO CacheStatistics)
8485
, cEpoch :: !(StrictTVar IO CacheEpoch)
86+
, cAddress :: !(StrictTVar IO (LRUCache ByteString V.AddressId))
8587
, cTxIds :: !(StrictTVar IO (FIFOCache (Ledger.TxId StandardCrypto) DB.TxId))
8688
}
8789

@@ -96,13 +98,16 @@ data CacheStatistics = CacheStatistics
9698
, multiAssetsQueries :: !Word64
9799
, prevBlockHits :: !Word64
98100
, prevBlockQueries :: !Word64
101+
, addressHits :: !Word64
102+
, addressQueries :: !Word64
99103
, txIdsHits :: !Word64
100104
, txIdsQueries :: !Word64
101105
}
102106

103107
-- CacheCapacity is used to define capacities for different types of cache entries.
104108
data CacheCapacity = CacheCapacity
105-
{ cacheCapacityStake :: !Word64
109+
{ cacheCapacityAddress :: !Word64
110+
, cacheCapacityStake :: !Word64
106111
, cacheCapacityDatum :: !Word64
107112
, cacheCapacityMultiAsset :: !Word64
108113
, cacheCapacityTx :: !Word64
@@ -128,7 +133,7 @@ data CacheEpoch = CacheEpoch
128133
deriving (Show)
129134

130135
textShowStats :: CacheStatus -> IO Text
131-
textShowStats NoCache = pure "NoCache"
136+
textShowStats NoCache = pure "No Caches"
132137
textShowStats (ActiveCache ic) = do
133138
isCacheOptimised <- readTVarIO $ cIsCacheOptimised ic
134139
stats <- readTVarIO $ cStats ic
@@ -137,77 +142,77 @@ textShowStats (ActiveCache ic) = do
137142
datums <- readTVarIO (cDatum ic)
138143
mAssets <- readTVarIO (cMultiAssets ic)
139144
txIds <- readTVarIO (cTxIds ic)
145+
address <- readTVarIO (cAddress ic)
140146
pure $
141147
mconcat
142148
[ "\nCache Statistics:"
143149
, "\n Caches Optimised: " <> textShow isCacheOptimised
144-
, "\n Stake Addresses: "
145-
, "cache sizes: "
146-
, textShow (Map.size $ scStableCache stakeHashRaws)
147-
, " and "
148-
, textShow (LRU.getSize $ scLruCache stakeHashRaws)
149-
, if credsQueries stats == 0
150-
then ""
151-
else ", hit rate: " <> textShow (100 * credsHits stats `div` credsQueries stats) <> "%"
152-
, ", hits: "
153-
, textShow (credsHits stats)
154-
, ", misses: "
155-
, textShow (credsQueries stats - credsHits stats)
156-
, "\n Pools: "
157-
, "cache size: "
158-
, textShow (Map.size pools)
159-
, if poolsQueries stats == 0
160-
then ""
161-
else ", hit rate: " <> textShow (100 * poolsHits stats `div` poolsQueries stats) <> "%"
162-
, ", hits: "
163-
, textShow (poolsHits stats)
164-
, ", misses: "
165-
, textShow (poolsQueries stats - poolsHits stats)
166-
, "\n Datums: "
167-
, "cache capacity: "
168-
, textShow (LRU.getCapacity datums)
169-
, ", cache size: "
170-
, textShow (LRU.getSize datums)
171-
, if datumQueries stats == 0
172-
then ""
173-
else ", hit rate: " <> textShow (100 * datumHits stats `div` datumQueries stats) <> "%"
174-
, ", hits: "
175-
, textShow (datumHits stats)
176-
, ", misses: "
177-
, textShow (datumQueries stats - datumHits stats)
178-
, "\n Multi Assets: "
179-
, "cache capacity: "
180-
, textShow (LRU.getCapacity mAssets)
181-
, ", cache size: "
182-
, textShow (LRU.getSize mAssets)
183-
, if multiAssetsQueries stats == 0
184-
then ""
185-
else ", hit rate: " <> textShow (100 * multiAssetsHits stats `div` multiAssetsQueries stats) <> "%"
186-
, ", hits: "
187-
, textShow (multiAssetsHits stats)
188-
, ", misses: "
189-
, textShow (multiAssetsQueries stats - multiAssetsHits stats)
190-
, "\n Previous Block: "
191-
, if prevBlockQueries stats == 0
192-
then ""
193-
else "hit rate: " <> textShow (100 * prevBlockHits stats `div` prevBlockQueries stats) <> "%"
194-
, ", hits: "
195-
, textShow (prevBlockHits stats)
196-
, ", misses: "
197-
, textShow (prevBlockQueries stats - prevBlockHits stats)
198-
, "\n TxId: "
199-
, "cache size: "
200-
, textShow (FIFO.getSize txIds)
201-
, ", cache capacity: "
202-
, textShow (FIFO.getCapacity txIds)
203-
, if txIdsQueries stats == 0
204-
then ""
205-
else ", hit rate: " <> textShow (100 * txIdsHits stats `div` txIdsQueries stats) <> "%"
206-
, ", hits: "
207-
, textShow (txIdsHits stats)
208-
, ", misses: "
209-
, textShow (txIdsQueries stats - txIdsHits stats)
150+
, textCacheSection "Stake Addresses" (scLruCache stakeHashRaws) (scStableCache stakeHashRaws) (credsHits stats) (credsQueries stats)
151+
, textMapSection "Pools" pools (poolsHits stats) (poolsQueries stats)
152+
, textLruSection "Datums" datums (datumHits stats) (datumQueries stats)
153+
, textLruSection "Addresses" address (addressHits stats) (addressQueries stats)
154+
, textLruSection "Multi Assets" mAssets (multiAssetsHits stats) (multiAssetsQueries stats)
155+
, textPrevBlockSection stats
156+
, textFifoSection "TxId" txIds (txIdsHits stats) (txIdsQueries stats)
210157
]
158+
where
159+
textCacheSection title cacheLru cacheStable hits queries =
160+
mconcat
161+
[ "\n " <> title <> ": "
162+
, "cache sizes: "
163+
, textShow (Map.size cacheStable)
164+
, " and "
165+
, textShow (LRU.getSize cacheLru)
166+
, hitMissStats hits queries
167+
]
168+
169+
textMapSection title cache hits queries =
170+
mconcat
171+
[ "\n " <> title <> ": "
172+
, "cache size: "
173+
, textShow (Map.size cache)
174+
, hitMissStats hits queries
175+
]
176+
177+
textLruSection title cache hits queries =
178+
mconcat
179+
[ "\n " <> title <> ": "
180+
, "cache capacity: "
181+
, textShow (LRU.getCapacity cache)
182+
, ", cache size: "
183+
, textShow (LRU.getSize cache)
184+
, hitMissStats hits queries
185+
]
186+
187+
textFifoSection title cache hits queries =
188+
mconcat
189+
[ "\n " <> title <> ": "
190+
, "cache size: "
191+
, textShow (FIFO.getSize cache)
192+
, ", cache capacity: "
193+
, textShow (FIFO.getCapacity cache)
194+
, hitMissStats hits queries
195+
]
196+
197+
textPrevBlockSection stats =
198+
mconcat
199+
[ "\n Previous Block: "
200+
, hitMissStats (prevBlockHits stats) (prevBlockQueries stats)
201+
]
202+
203+
hitMissStats hits queries =
204+
mconcat
205+
[ hitRate hits queries
206+
, ", hits: "
207+
, textShow hits
208+
, ", misses: "
209+
, textShow (queries - hits)
210+
]
211+
212+
hitRate hits queries =
213+
if queries == 0
214+
then ""
215+
else ", hit rate: " <> textShow (100 * hits `div` queries) <> "%"
211216

212217
useNoCache :: CacheStatus
213218
useNoCache = NoCache
@@ -218,6 +223,7 @@ newEmptyCache CacheCapacity {..} = liftIO $ do
218223
cStake <- newTVarIO (StakeCache Map.empty (LRU.empty cacheCapacityStake))
219224
cPools <- newTVarIO Map.empty
220225
cDatum <- newTVarIO (LRU.empty cacheCapacityDatum)
226+
cAddress <- newTVarIO (LRU.empty cacheCapacityAddress)
221227
cMultiAssets <- newTVarIO (LRU.empty cacheCapacityMultiAsset)
222228
cPrevBlock <- newTVarIO Nothing
223229
cStats <- newTVarIO initCacheStatistics
@@ -234,11 +240,12 @@ newEmptyCache CacheCapacity {..} = liftIO $ do
234240
, cPrevBlock = cPrevBlock
235241
, cStats = cStats
236242
, cEpoch = cEpoch
243+
, cAddress = cAddress
237244
, cTxIds = cTxIds
238245
}
239246

240247
initCacheStatistics :: CacheStatistics
241-
initCacheStatistics = CacheStatistics 0 0 0 0 0 0 0 0 0 0 0 0
248+
initCacheStatistics = CacheStatistics 0 0 0 0 0 0 0 0 0 0 0 0 0 0
242249

243250
initCacheEpoch :: CacheEpoch
244251
initCacheEpoch = CacheEpoch mempty Nothing

cardano-db-sync/src/Cardano/DbSync/Era/Byron/Genesis.hs

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import qualified Cardano.Db.Schema.Core.TxOut as C
2121
import qualified Cardano.Db.Schema.Variant.TxOut as V
2222
import Cardano.DbSync.Api
2323
import Cardano.DbSync.Api.Types (SyncEnv (..))
24+
import Cardano.DbSync.Cache (insertAddressUsingCache)
25+
import Cardano.DbSync.Cache.Types (CacheAction (..))
2426
import Cardano.DbSync.Config.Types
2527
import qualified Cardano.DbSync.Era.Byron.Util as Byron
2628
import Cardano.DbSync.Era.Util (liftLookupFail)
@@ -228,10 +230,12 @@ insertTxOutsByron syncEnv disInOut blkId (address, value) = do
228230
DB.TxOutVariantAddress -> do
229231
let addrRaw = serialize' address
230232
vAddress = mkVAddress addrRaw
231-
addrDetailId <- insertAddress addrRaw vAddress
233+
addrDetailId <- insertAddressUsingCache cache UpdateCache addrRaw vAddress
232234
void . DB.insertTxOut $
233235
DB.VTxOutW (mkVTxOut txId addrDetailId) Nothing
234236
where
237+
cache = envCache syncEnv
238+
235239
mkVTxOut :: DB.TxId -> V.AddressId -> V.TxOut
236240
mkVTxOut txId addrDetailId =
237241
V.TxOut
@@ -256,19 +260,7 @@ insertTxOutsByron syncEnv disInOut blkId (address, value) = do
256260
, V.addressStakeAddressId = Nothing -- Byron does not have a stake address.
257261
}
258262

259-
insertAddress ::
260-
(MonadBaseControl IO m, MonadIO m) =>
261-
ByteString ->
262-
V.Address ->
263-
ReaderT SqlBackend m V.AddressId
264-
insertAddress addrRaw vAdrs = do
265-
mAddrId <- DB.queryAddressId addrRaw
266-
case mAddrId of
267-
Nothing -> DB.insertAddress vAdrs
268-
-- this address is already in the database, so we can just return the id to be linked to the txOut.
269-
Just addrId -> pure addrId
270-
271-
-- -----------------------------------------------------------------------------
263+
---------------------------------------------------------------------------------
272264

273265
configGenesisHash :: Byron.Config -> ByteString
274266
configGenesisHash =

cardano-db-sync/src/Cardano/DbSync/Era/Byron/Insert.hs

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@ import qualified Cardano.Db.Schema.Variant.TxOut as V
2525
import Cardano.DbSync.Api
2626
import Cardano.DbSync.Api.Types (InsertOptions (..), SyncEnv (..), SyncOptions (..))
2727
import Cardano.DbSync.Cache (
28+
insertAddressUsingCache,
2829
insertBlockAndCache,
2930
queryPrevBlockWithCache,
3031
)
3132
import Cardano.DbSync.Cache.Epoch (writeEpochBlockDiffToCache)
32-
import Cardano.DbSync.Cache.Types (CacheStatus (..), EpochBlockDiff (..))
33+
import Cardano.DbSync.Cache.Types (CacheAction (..), CacheStatus (..), EpochBlockDiff (..))
3334
import qualified Cardano.DbSync.Era.Byron.Util as Byron
3435
import Cardano.DbSync.Era.Util (liftLookupFail)
3536
import Cardano.DbSync.Error
@@ -366,12 +367,14 @@ insertTxOutByron syncEnv _hasConsumed bootStrap txId index txout =
366367
, C.txOutValue = DbLovelace (Byron.unsafeGetLovelace $ Byron.txOutValue txout)
367368
}
368369
DB.TxOutVariantAddress -> do
369-
addrDetailId <- insertAddress
370+
addrDetailId <- insertAddressUsingCache cache UpdateCache addrRaw vAddress
370371
void . DB.insertTxOut $ DB.VTxOutW (vTxOut addrDetailId) Nothing
371372
where
372373
addrRaw :: ByteString
373374
addrRaw = serialize' (Byron.txOutAddress txout)
374375

376+
cache = envCache syncEnv
377+
375378
vTxOut :: V.AddressId -> V.TxOut
376379
vTxOut addrDetailId =
377380
V.TxOut
@@ -396,16 +399,6 @@ insertTxOutByron syncEnv _hasConsumed bootStrap txId index txout =
396399
, V.addressStakeAddressId = Nothing -- Byron does not have a stake address.
397400
}
398401

399-
insertAddress ::
400-
(MonadBaseControl IO m, MonadIO m) =>
401-
ReaderT SqlBackend m V.AddressId
402-
insertAddress = do
403-
mAddrId <- DB.queryAddressId addrRaw
404-
case mAddrId of
405-
Nothing -> DB.insertAddress vAddress
406-
-- this address is already in the database, so we can just return the id to be linked to the txOut.
407-
Just addrId -> pure addrId
408-
409402
insertTxIn ::
410403
(MonadBaseControl IO m, MonadIO m) =>
411404
Trace IO Text ->

0 commit comments

Comments
 (0)