diff options
| author | Roman Smrž <roman.smrz@seznam.cz> | 2026-02-10 12:07:59 +0100 |
|---|---|---|
| committer | Roman Smrž <roman.smrz@seznam.cz> | 2026-02-10 12:39:34 +0100 |
| commit | f79d7088766b99421c56d85244bccdfd94f8670f (patch) | |
| tree | 8962a6510934bef7601f0dea6b9720b24422d8e6 /src/Storage/Cache.hs | |
| parent | ccf3ccb7e1e8d839c000854b9078a1b143c791e3 (diff) | |
Cache storage
Diffstat (limited to 'src/Storage/Cache.hs')
| -rw-r--r-- | src/Storage/Cache.hs | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/src/Storage/Cache.hs b/src/Storage/Cache.hs new file mode 100644 index 0000000..9be59c2 --- /dev/null +++ b/src/Storage/Cache.hs @@ -0,0 +1,96 @@ +module Storage.Cache ( + cacheStorage, +) where + +import Control.Concurrent + +import Data.ByteString qualified as B +import Data.ByteString.Lazy qualified as BL +import Data.Function +import Data.Map (Map) +import Data.Map qualified as M + +import Erebos.Object +import Erebos.Storage.Backend +import Erebos.Storage.Head + +import Storage.WatchList + + +data CacheStorage = StorageCache + { cacheParent :: Storage + , cacheHeads :: MVar [ (( HeadTypeID, HeadID ), RefDigest ) ] + , cacheObjs :: MVar (Map RefDigest BL.ByteString) + , cacheKeys :: MVar (Map RefDigest B.ByteString) + , cacheWatchers :: MVar WatchList + } + +instance Eq CacheStorage where + (==) = (==) `on` cacheObjs + +instance Show CacheStorage where + show StorageCache {} = "cache" + +instance StorageBackend CacheStorage where + backendLoadBytes StorageCache {..} dgst = + (M.lookup dgst <$> readMVar cacheObjs) >>= \case + x@Just {} -> return x + Nothing -> withStorageBackend cacheParent $ \bck -> do + backendLoadBytes bck dgst >>= \case + x@(Just raw) -> do + modifyMVar_ cacheObjs (return . M.insert dgst raw) + return x + Nothing -> return Nothing + + backendStoreBytes StorageCache {..} dgst raw = do + modifyMVar_ cacheObjs (return . M.insert dgst raw) + withStorageBackend cacheParent $ \bck -> + backendStoreBytes bck dgst raw + + + backendLoadHeads StorageCache {..} tid = do + withStorageBackend cacheParent $ \bck -> + backendLoadHeads bck tid + + backendLoadHead StorageCache {..} tid hid = + withStorageBackend cacheParent $ \bck -> + backendLoadHead bck tid hid + + backendStoreHead StorageCache {..} tid hid dgst = + withStorageBackend cacheParent $ \bck -> + backendStoreHead bck tid hid dgst + + backendReplaceHead StorageCache {..} tid hid expected new = do + withStorageBackend cacheParent $ \bck -> + backendReplaceHead bck tid hid expected new + + backendWatchHead StorageCache {..} tid hid cb = do + withStorageBackend cacheParent $ \bck -> + backendWatchHead bck tid hid cb + + backendUnwatchHead StorageCache {..} wid = do + withStorageBackend cacheParent $ \bck -> + backendUnwatchHead bck wid + + + backendListKeys StorageCache {..} = do + withStorageBackend cacheParent $ \bck -> + backendListKeys bck + backendLoadKey StorageCache {..} dgst = do + withStorageBackend cacheParent $ \bck -> + backendLoadKey bck dgst + backendStoreKey StorageCache {..} dgst key = do + withStorageBackend cacheParent $ \bck -> + backendStoreKey bck dgst key + backendRemoveKey StorageCache {..} dgst = do + withStorageBackend cacheParent $ \bck -> + backendRemoveKey bck dgst + + +cacheStorage :: Storage -> IO Storage +cacheStorage cacheParent = do + cacheHeads <- newMVar [] + cacheObjs <- newMVar M.empty + cacheKeys <- newMVar M.empty + cacheWatchers <- newMVar (WatchList startWatchID []) + newStorage $ StorageCache {..} |