A cache that supports pinning of data, so that it'll stay in the cache until the user decides they don't need it anymore It's created to be used with HTTP-Requests
The cache itself. The decoder is a decoder for the data type that will be saved in the cache
Shows if the data was found in the cache (which returns the cache itself and the requested data), or, if it wasn't found, the HTTP-Request to get the data
GetDataDBElement target ->
case Pcache.get target model.dbelementcache of
Pcache.InCache ( cache, data ) ->
( { model | dbelementcache = cache }, Cmd.none )
Pcache.CacheMiss request ->
( model, Http.send (LoadData target) request )
Create an empty cache with a variable least recently used-cache size Needs a decoder for the data type that's to be saved in the cachesize
dbelementcache = Pcache.empty 3 decodeDB
Pin data to keep it in cache permanently "target" is supposed to be the path to the requested data
Pcache.pin target data model.dbelementcache
Save data to store it directly in the least recently used-cache "target" is supposed to be the path to the requested data
Pcache.save target data model.dbelementcache
Unpin data to store it in least recently used-cache "target" is supposed to be the path to the requested data
Pcache.unpin target model.dbelementcache
Search for data in cache, returns a pair of (Cache, data) if found, the HTTP-Request to find the data if not found. "target" is supposed to be the path to the requested data
Pcache.get target model.dbelementcache
module PinnableCache exposing (Pcache, ReturnData(InCache, CacheMiss), empty, pin, save, unpin, get)
{-| A cache that supports pinning of data, so that it'll stay in the cache until the user decides they don't need it anymore
It's created to be used with HTTP-Requests
@docs Pcache, ReturnData, empty, pin, save, unpin, get
-}
import LruCache
import Http
import Dict
import Json.Decode as Decode
{-| The cache itself. The decoder is a decoder for the data type that will be saved in the cache
-}
type alias Pcache a =
{ cache : Dict.Dict String a
, lrucache : LruCache.LruCache String a
, decoder : Decode.Decoder a
, log : String
}
{-| Shows if the data was found in the cache (which returns the cache itself and the requested data), or, if it wasn't found, the HTTP-Request to get the data
GetDataDBElement target ->
case Pcache.get target model.dbelementcache of
Pcache.InCache ( cache, data ) ->
( { model | dbelementcache = cache }, Cmd.none )
Pcache.CacheMiss request ->
( model, Http.send (LoadData target) request )
-}
type ReturnData a
= InCache ( Pcache a, a )
| CacheMiss (Http.Request a)
{-| Create an empty cache with a variable least recently used-cache size
Needs a decoder for the data type that's to be saved in the cachesize
dbelementcache = Pcache.empty 3 decodeDB
-}
empty : Int -> Decode.Decoder a -> Pcache a
empty cachesize decoder =
{ cache = Dict.empty
, lrucache = LruCache.empty cachesize
, decoder = decoder
, log = "No Error"
}
{-| Pin data to keep it in cache permanently
"target" is supposed to be the path to the requested data
Pcache.pin target data model.dbelementcache
-}
pin : String -> a -> Pcache a -> Pcache a
pin target data cache =
if (Dict.member target cache.cache == False) then
{ cache | cache = Dict.insert target data cache.cache, log = "Successfully pinned data" }
else
{ cache | log = "Data already pinned" }
{-| Save data to store it directly in the least recently used-cache
"target" is supposed to be the path to the requested data
Pcache.save target data model.dbelementcache
-}
save : String -> a -> Pcache a -> Pcache a
save target data cache =
{ cache
| lrucache = LruCache.insert target data cache.lrucache
, log = "Successfully saved data in cache!"
}
{-| Unpin data to store it in least recently used-cache
"target" is supposed to be the path to the requested data
Pcache.unpin target model.dbelementcache
-}
unpin : String -> Pcache a -> Pcache a
unpin target cache =
case Dict.get target cache.cache of
Just a ->
{ cache
| cache = Dict.remove target cache.cache
, lrucache = LruCache.insert target a cache.lrucache
, log = "Successfully unpinned data"
}
Nothing ->
{ cache | log = "No data found to unpin" }
{-| Search for data in cache, returns a pair of (Cache, data) if found, the HTTP-Request to find the data if not found.
"target" is supposed to be the path to the requested data
Pcache.get target model.dbelementcache
-}
get : String -> Pcache a -> ReturnData a
get target cache =
case Dict.get target cache.cache of
Just data ->
InCache
( { cache
| cache = Dict.insert target data cache.cache
, log = "Found data in cache"
}
, data
)
Nothing ->
case LruCache.get target cache.lrucache of
( newlrucache, Just a ) ->
InCache
( { cache
| cache = Dict.insert target a cache.cache
, lrucache = newlrucache
, log = "Found data in lrucache"
}
, a
)
( newlrucache, Nothing ) ->
CacheMiss (Http.get target cache.decoder)