dfinity-radix-tree-0.1.0: src/Network/DFINITY/RadixTree/Memory.hs
{-# OPTIONS -Wall #-}
module Network.DFINITY.RadixTree.Memory
( loadHot
, loadCold
, storeHot
, storeCold
) where
import Codec.Serialise (deserialise, serialise)
import Control.Monad.Trans.Resource (ResourceT)
import Crypto.Hash.SHA256 (hash)
import Data.ByteString.Char8 as Byte (take)
import Data.ByteString.Lazy (fromStrict, toStrict)
import Data.ByteString.Short (fromShort, toShort)
import Data.LruCache as LRU (insert, lookup)
import Data.Map.Strict as Map (insert, lookup)
import Database.LevelDB (DB)
import Network.DFINITY.RadixTree.Types
loadHot
:: RadixDatabase config m database
=> RadixRoot
-> RadixBuffer
-> RadixCache
-> database
-> m (Maybe (RadixBranch, RadixCache))
{-# SPECIALISE loadHot
:: RadixRoot
-> RadixBuffer
-> RadixCache
-> DB
-> ResourceT IO (Maybe (RadixBranch, RadixCache)) #-}
loadHot root buffer cache database =
case Map.lookup root buffer of
Just branch -> pure $ Just (branch, cache)
Nothing -> loadCold root cache database
loadCold
:: RadixDatabase config m database
=> RadixRoot
-> RadixCache
-> database
-> m (Maybe (RadixBranch, RadixCache))
{-# SPECIALISE loadCold
:: RadixRoot
-> RadixCache
-> DB
-> ResourceT IO (Maybe (RadixBranch, RadixCache)) #-}
loadCold root cache database =
case LRU.lookup root cache of
Just (branch, cache') ->
seq cache' $ seq branch $ pure $ Just (branch, cache')
Nothing -> do
let key = fromShort root
result <- load database key
case result of
Just bytes -> do
let branch = deserialise $ fromStrict bytes
let cache' = LRU.insert root branch cache
seq cache' $ seq branch $ pure $ Just (branch, cache')
Nothing -> pure $ Nothing
storeHot
:: RadixRoot
-> RadixBranch
-> RadixBuffer
-> RadixBuffer
storeHot = Map.insert
storeCold
:: RadixDatabase config m database
=> RadixBranch
-> RadixCache
-> database
-> m (RadixRoot, RadixCache)
{-# SPECIALISE storeCold
:: RadixBranch
-> RadixCache
-> DB
-> ResourceT IO (RadixRoot, RadixCache) #-}
storeCold branch cache database = do
store database key bytes
seq cache' $ pure (root, cache')
where
bytes = toStrict $ serialise branch
key = Byte.take 20 $ hash bytes
root = toShort key
cache' = LRU.insert root branch cache