{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# LANGUAGE ScopedTypeVariables, ExistentialQuantification,
FlexibleInstances, UndecidableInstances #-}
module Data.TCache (
atomically
,atomicallySync
,STM
,unsafeIOToSTM
,safeIOToSTM
,DBRef
,getDBRef
,keyObjDBRef
,newDBRef
,readDBRef
,readDBRefs
,writeDBRef
,delDBRef
,IResource(..)
,Resources(..)
,resources
,withSTMResources
,withResources
,withResource
,getResources
,getResource
,deleteResources
,deleteResource
,addTrigger
,flushDBRef
,flushKey
,invalidateKey
,flushAll
,Cache
,setCache
,newCache
,syncCache
,setConditions
,clearSyncCache
,numElems
,statElems
,syncWrite
,SyncMode(..)
,clearSyncCacheProc
,defaultCheck
,onNothing
)
where
import GHC.Conc
import GHC.MVar(MVar)
import Control.Monad(when, void)
import qualified Data.HashTable.IO as H(BasicHashTable, new, insert, lookup, toList)
import Data.IORef(IORef, newIORef, readIORef, writeIORef)
import System.IO.Unsafe(unsafePerformIO)
import System.IO(hPutStr, stderr)
import Data.Maybe(catMaybes)
import Data.Foldable(forM_)
import Data.Char(isSpace)
import Data.TCache.Defs
import Data.TCache.IResource
import Data.TCache.Triggers
import Data.Typeable(Typeable)
import System.Time(getClockTime, ClockTime(TOD))
import System.Mem(performGC)
import System.Mem.Weak(Weak, deRefWeak, mkWeakPtr, finalize)
import Control.Concurrent.MVar(newMVar, newEmptyMVar, takeMVar, putMVar)
import Control.Exception(catch, handle, throw, evaluate, bracket, SomeException)
data CacheElem= forall a.(IResource a,Typeable a) => CacheElem (Maybe (DBRef a)) (Weak(DBRef a))
type Ht = H.BasicHashTable String CacheElem
type Cache = IORef (Ht , Integer)
data CheckTPVarFlags= AddToHash | NoAddToHash
setCache :: Cache -> IO()
setCache :: Cache -> IO ()
setCache Cache
ref = forall a. IORef a -> IO a
readIORef Cache
ref forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \(HashTable RealWorld String CacheElem, Integer)
ch -> forall a. IORef a -> a -> IO ()
writeIORef Cache
refcache (HashTable RealWorld String CacheElem, Integer)
ch
refcache :: Cache
{-# NOINLINE refcache #-}
refcache :: Cache
refcache =forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ IO (Ht, Integer)
newCache forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a. a -> IO (IORef a)
newIORef
newCache :: IO (Ht , Integer)
newCache :: IO (Ht, Integer)
newCache =do
HashTable RealWorld String CacheElem
c <- forall (h :: * -> * -> * -> *) k v.
HashTable h =>
IO (IOHashTable h k v)
H.new
forall (m :: * -> *) a. Monad m => a -> m a
return (HashTable RealWorld String CacheElem
c,Integer
0)
numElems :: IO Int
numElems :: IO Int
numElems= do
(HashTable RealWorld String CacheElem
cache, Integer
_) <- forall a. IORef a -> IO a
readIORef Cache
refcache
[(String, CacheElem)]
elems <- forall (h :: * -> * -> * -> *) k v.
(HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> IO [(k, v)]
H.toList HashTable RealWorld String CacheElem
cache
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Int
length [(String, CacheElem)]
elems
statElems :: IO (Int, Int, Int)
statElems :: IO (Int, Int, Int)
statElems = do
(HashTable RealWorld String CacheElem
cache, Integer
lastSync) <- forall a. IORef a -> IO a
readIORef Cache
refcache
[(String, CacheElem)]
clist <- forall (h :: * -> * -> * -> *) k v.
(HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> IO [(k, v)]
H.toList HashTable RealWorld String CacheElem
cache
([Filtered]
tosave, [CacheElem]
elems, Int
size) <- forall a. STM a -> IO a
atomically forall a b. (a -> b) -> a -> b
$ forall a.
[(a, CacheElem)] -> Integer -> STM ([Filtered], [CacheElem], Int)
extract [(String, CacheElem)]
clist Integer
lastSync
[Int]
counted <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall {b}. Num b => CacheElem -> IO b
count [CacheElem]
elems
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
size, forall (t :: * -> *) a. Foldable t => t a -> Int
length [Filtered]
tosave, forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Int]
counted)
where
count :: CacheElem -> IO b
count (CacheElem Maybe (DBRef a)
_ Weak (DBRef a)
w) = do
Maybe (DBRef a)
mr <- forall v. Weak v -> IO (Maybe v)
deRefWeak Weak (DBRef a)
w
case Maybe (DBRef a)
mr of
Just (DBRef String
_ TPVar a
tv) -> do
Status (Elem a)
r <- forall a. TVar a -> IO a
readTVarIO TPVar a
tv
case Status (Elem a)
r of
Exist Elem {} -> forall (m :: * -> *) a. Monad m => a -> m a
return b
1
Status (Elem a)
DoNotExist -> forall (m :: * -> *) a. Monad m => a -> m a
return b
0
Status (Elem a)
NotRead -> forall (m :: * -> *) a. Monad m => a -> m a
return b
0
Maybe (DBRef a)
Nothing -> forall v. Weak v -> IO ()
finalize Weak (DBRef a)
w forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return b
0
fixToCache :: (IResource a, Typeable a) => DBRef a -> IO ()
fixToCache :: forall a. (IResource a, Typeable a) => DBRef a -> IO ()
fixToCache dbref :: DBRef a
dbref@(DBRef String
k TPVar a
_)= do
(HashTable RealWorld String CacheElem
cache, Integer
_) <- forall a. IORef a -> IO a
readIORef Cache
refcache
Weak (DBRef a)
w <- forall k. k -> Maybe (IO ()) -> IO (Weak k)
mkWeakPtr DBRef a
dbref forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. (IResource a, Typeable a) => DBRef a -> IO ()
fixToCache DBRef a
dbref
forall (h :: * -> * -> * -> *) k v.
(HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> k -> v -> IO ()
H.insert HashTable RealWorld String CacheElem
cache String
k (forall a.
(IResource a, Typeable a) =>
Maybe (DBRef a) -> Weak (DBRef a) -> CacheElem
CacheElem (forall a. a -> Maybe a
Just DBRef a
dbref) Weak (DBRef a)
w)
forall (m :: * -> *) a. Monad m => a -> m a
return()
readDBRef :: (IResource a, Typeable a) => DBRef a -> STM (Maybe a)
readDBRef :: forall a. (IResource a, Typeable a) => DBRef a -> STM (Maybe a)
readDBRef (DBRef String
key1 TPVar a
tv)= do
Status (Elem a)
r <- forall a. TVar a -> STM a
readTVar TPVar a
tv
case Status (Elem a)
r of
Exist (Elem a
x Integer
_ Integer
mt) -> do
Integer
t <- forall a. IO a -> STM a
unsafeIOToSTM IO Integer
timeInteger
forall a. TVar a -> a -> STM ()
writeTVar TPVar a
tv forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Status a
Exist forall a b. (a -> b) -> a -> b
$ forall a. a -> Integer -> Integer -> Elem a
Elem a
x Integer
t Integer
mt
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just a
x
Status (Elem a)
DoNotExist -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
Status (Elem a)
NotRead -> do
Maybe a
r1 <- forall a. IO a -> STM a
safeIOToSTM forall a b. (a -> b) -> a -> b
$ forall a. IResource a => String -> IO (Maybe a)
readResourceByKey String
key1
case Maybe a
r1 of
Maybe a
Nothing -> forall a. TVar a -> a -> STM ()
writeTVar TPVar a
tv forall a. Status a
DoNotExist forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
Just a
x -> do
Integer
t <- forall a. IO a -> STM a
unsafeIOToSTM IO Integer
timeInteger
forall a. TVar a -> a -> STM ()
writeTVar TPVar a
tv forall a b. (a -> b) -> a -> b
$ forall a. a -> Status a
Exist forall a b. (a -> b) -> a -> b
$ forall a. a -> Integer -> Integer -> Elem a
Elem a
x Integer
t (-Integer
1)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just a
x
readDBRefs :: (IResource a, Typeable a) => [DBRef a] -> STM [Maybe a]
readDBRefs :: forall a. (IResource a, Typeable a) => [DBRef a] -> STM [Maybe a]
readDBRefs [DBRef a]
dbrefs= do
let mf :: DBRef a -> STM (Either String (Maybe a))
mf (DBRef String
key1 TPVar a
tv)= do
Status (Elem a)
r <- forall a. TVar a -> STM a
readTVar TPVar a
tv
case Status (Elem a)
r of
Exist (Elem a
x Integer
_ Integer
mt) -> do
Integer
t <- forall a. IO a -> STM a
unsafeIOToSTM IO Integer
timeInteger
forall a. TVar a -> a -> STM ()
writeTVar TPVar a
tv forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Status a
Exist forall a b. (a -> b) -> a -> b
$ forall a. a -> Integer -> Integer -> Elem a
Elem a
x Integer
t Integer
mt
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just a
x
Status (Elem a)
DoNotExist -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. b -> Either a b
Right forall a. Maybe a
Nothing
Status (Elem a)
NotRead -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left String
key1
[Either String (Maybe a)]
inCache <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall {a}. DBRef a -> STM (Either String (Maybe a))
mf [DBRef a]
dbrefs
let pairs :: [(Either String (Maybe a), DBRef a)]
pairs = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr(\pair :: (Either String (Maybe a), DBRef a)
pair@(Either String (Maybe a)
x,DBRef a
_) [(Either String (Maybe a), DBRef a)]
xs -> case Either String (Maybe a)
x of Left String
_ -> (Either String (Maybe a), DBRef a)
pairforall a. a -> [a] -> [a]
:[(Either String (Maybe a), DBRef a)]
xs; Either String (Maybe a)
_ -> [(Either String (Maybe a), DBRef a)]
xs ) [] forall a b. (a -> b) -> a -> b
$ forall a b. [a] -> [b] -> [(a, b)]
zip [Either String (Maybe a)]
inCache [DBRef a]
dbrefs
let ([Either String (Maybe a)]
toReadKeys, [DBRef a]
dbrs) = forall a b. [(a, b)] -> ([a], [b])
unzip [(Either String (Maybe a), DBRef a)]
pairs
let fromLeft :: Either a b -> a
fromLeft (Left a
k)= a
k
fromLeft Either a b
_ = forall a. HasCallStack => String -> a
error String
"this will never happen"
[Maybe a]
rs <- forall a. IO a -> STM a
safeIOToSTM forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. IResource a => [String] -> IO [Maybe a]
readResourcesByKey forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall {a} {b}. Either a b -> a
fromLeft [Either String (Maybe a)]
toReadKeys
let processTVar :: (Maybe a, DBRef a) -> STM ()
processTVar (Maybe a
r, DBRef String
_ TPVar a
tv)=
case Maybe a
r of
Maybe a
Nothing -> forall a. TVar a -> a -> STM ()
writeTVar TPVar a
tv forall a. Status a
DoNotExist
Just a
x -> do
Integer
t <- forall a. IO a -> STM a
unsafeIOToSTM IO Integer
timeInteger
forall a. TVar a -> a -> STM ()
writeTVar TPVar a
tv forall a b. (a -> b) -> a -> b
$ forall a. a -> Status a
Exist forall a b. (a -> b) -> a -> b
$ forall a. a -> Integer -> Integer -> Elem a
Elem a
x Integer
t (-Integer
1)
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall {a}. (Maybe a, DBRef a) -> STM ()
processTVar forall a b. (a -> b) -> a -> b
$ forall a b. [a] -> [b] -> [(a, b)]
zip [Maybe a]
rs [DBRef a]
dbrs
let mix :: [Either a a] -> [a] -> [a]
mix (Right a
x:[Either a a]
xs) [a]
ys = a
xforall a. a -> [a] -> [a]
:[Either a a] -> [a] -> [a]
mix [Either a a]
xs [a]
ys
mix (Left a
_:[Either a a]
xs) (a
y:[a]
ys)= a
yforall a. a -> [a] -> [a]
:[Either a a] -> [a] -> [a]
mix [Either a a]
xs [a]
ys
mix [] [a]
_ = forall a. HasCallStack => String -> a
error String
"this will never happen(?)"
mix (Left a
_:[Either a a]
_) [] = forall a. HasCallStack => String -> a
error String
"this will never happen(?)"
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall {a} {a}. [Either a a] -> [a] -> [a]
mix [Either String (Maybe a)]
inCache [Maybe a]
rs
writeDBRef :: (IResource a, Typeable a) => DBRef a -> a -> STM ()
writeDBRef :: forall a. (IResource a, Typeable a) => DBRef a -> a -> STM ()
writeDBRef dbref :: DBRef a
dbref@(DBRef String
key1 TPVar a
tv) a
x= a
x seq :: forall a b. a -> b -> b
`seq` do
let newkey :: String
newkey= forall a. IResource a => a -> String
keyResource a
x
if String
newkey forall a. Eq a => a -> a -> Bool
/= String
key1
then forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"writeDBRef: law of key conservation broken: old , new= " forall a. [a] -> [a] -> [a]
++ String
key1 forall a. [a] -> [a] -> [a]
++ String
" , "forall a. [a] -> [a] -> [a]
++String
newkey
else do
forall a.
(IResource a, Typeable a) =>
[DBRef a] -> [Maybe a] -> STM ()
applyTriggers [DBRef a
dbref] [forall a. a -> Maybe a
Just a
x]
Integer
t <- forall a. IO a -> STM a
unsafeIOToSTM IO Integer
timeInteger
forall a. TVar a -> a -> STM ()
writeTVar TPVar a
tv forall a b. (a -> b) -> a -> b
$! forall a. a -> Status a
Exist forall a b. (a -> b) -> a -> b
$! forall a. a -> Integer -> Integer -> Elem a
Elem a
x Integer
t Integer
t
forall (m :: * -> *) a. Monad m => a -> m a
return()
instance (IResource a, Typeable a) => Read (DBRef a) where
readsPrec :: Int -> ReadS (DBRef a)
readsPrec Int
_ String
str1= ReadS (DBRef a)
readit String
str
where
str :: String
str = forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isSpace String
str1
readit :: ReadS (DBRef a)
readit (Char
'D':Char
'B':Char
'R':Char
'e':Char
'f':Char
' ':Char
'\"':String
str2)=
let (String
key1,String
nstr) = forall a. (a -> Bool) -> [a] -> ([a], [a])
break (forall a. Eq a => a -> a -> Bool
== Char
'\"') String
str2
in [( forall a. (Typeable a, IResource a) => String -> DBRef a
getDBRef String
key1 :: DBRef a, forall a. [a] -> [a]
tail String
nstr)]
readit String
_ = []
keyObjDBRef :: DBRef a -> String
keyObjDBRef :: forall a. DBRef a -> String
keyObjDBRef (DBRef String
k TPVar a
_)= String
k
{-# NOINLINE getDBRef #-}
getDBRef :: (Typeable a, IResource a) => String -> DBRef a
getDBRef :: forall a. (Typeable a, IResource a) => String -> DBRef a
getDBRef String
key1 = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$! forall a. (Typeable a, IResource a) => String -> IO (DBRef a)
getDBRef1 forall a b. (a -> b) -> a -> b
$! String
key1 where
getDBRef1 :: (Typeable a, IResource a) => String -> IO (DBRef a)
getDBRef1 :: forall a. (Typeable a, IResource a) => String -> IO (DBRef a)
getDBRef1 String
key2 = do
(HashTable RealWorld String CacheElem
cache,Integer
_) <- forall a. IORef a -> IO a
readIORef Cache
refcache
forall a. MVar a -> IO a
takeMVar MVar ()
getRefFlag
Maybe CacheElem
r <- forall (h :: * -> * -> * -> *) k v.
(HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> k -> IO (Maybe v)
H.lookup HashTable RealWorld String CacheElem
cache String
key2
case Maybe CacheElem
r of
Just (CacheElem Maybe (DBRef a)
mdb Weak (DBRef a)
w) -> do
forall a. MVar a -> a -> IO ()
putMVar MVar ()
getRefFlag ()
Maybe (DBRef a)
mr <- forall v. Weak v -> IO (Maybe v)
deRefWeak Weak (DBRef a)
w
case Maybe (DBRef a)
mr of
Just dbref :: DBRef a
dbref@(DBRef String
_ TPVar a
_) ->
case Maybe (DBRef a)
mdb of
Maybe (DBRef a)
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$! forall a1 a2. (Typeable a1, Typeable a2) => a1 -> a2
castErr DBRef a
dbref
Just DBRef a
_ -> do
forall (h :: * -> * -> * -> *) k v.
(HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> k -> v -> IO ()
H.insert HashTable RealWorld String CacheElem
cache String
key2 (forall a.
(IResource a, Typeable a) =>
Maybe (DBRef a) -> Weak (DBRef a) -> CacheElem
CacheElem forall a. Maybe a
Nothing Weak (DBRef a)
w)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$! forall a1 a2. (Typeable a1, Typeable a2) => a1 -> a2
castErr DBRef a
dbref
Maybe (DBRef a)
Nothing -> forall v. Weak v -> IO ()
finalize Weak (DBRef a)
w forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. (Typeable a, IResource a) => String -> IO (DBRef a)
getDBRef1 String
key2
Maybe CacheElem
Nothing -> do
TVar (Status (Elem a))
tv <- forall a. a -> IO (TVar a)
newTVarIO forall a. Status a
NotRead
DBRef a
dbref <- forall a. a -> IO a
evaluate forall a b. (a -> b) -> a -> b
$ forall a. String -> TPVar a -> DBRef a
DBRef String
key2 TVar (Status (Elem a))
tv
Weak (DBRef a)
w <- forall k. k -> Maybe (IO ()) -> IO (Weak k)
mkWeakPtr DBRef a
dbref forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. (IResource a, Typeable a) => DBRef a -> IO ()
fixToCache DBRef a
dbref
forall (h :: * -> * -> * -> *) k v.
(HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> k -> v -> IO ()
H.insert HashTable RealWorld String CacheElem
cache String
key2 (forall a.
(IResource a, Typeable a) =>
Maybe (DBRef a) -> Weak (DBRef a) -> CacheElem
CacheElem forall a. Maybe a
Nothing Weak (DBRef a)
w)
forall a. MVar a -> a -> IO ()
putMVar MVar ()
getRefFlag ()
forall (m :: * -> *) a. Monad m => a -> m a
return DBRef a
dbref
getRefFlag :: MVar ()
{-# NOINLINE getRefFlag #-}
getRefFlag :: MVar ()
getRefFlag= forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ forall a. a -> IO (MVar a)
newMVar ()
{-# NOINLINE newDBRef #-}
newDBRef :: (IResource a, Typeable a) => a -> STM (DBRef a)
newDBRef :: forall a. (IResource a, Typeable a) => a -> STM (DBRef a)
newDBRef a
x = do
let ref :: DBRef a
ref= forall a. (Typeable a, IResource a) => String -> DBRef a
getDBRef forall a b. (a -> b) -> a -> b
$! forall a. IResource a => a -> String
keyResource a
x
Maybe a
mr <- forall a. (IResource a, Typeable a) => DBRef a -> STM (Maybe a)
readDBRef DBRef a
ref
case Maybe a
mr of
Maybe a
Nothing -> forall a. (IResource a, Typeable a) => DBRef a -> a -> STM ()
writeDBRef DBRef a
ref a
x forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return DBRef a
ref
Just a
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return DBRef a
ref
delDBRef :: (IResource a, Typeable a) => DBRef a -> STM()
delDBRef :: forall a. (IResource a, Typeable a) => DBRef a -> STM ()
delDBRef dbref :: DBRef a
dbref@(DBRef String
_ TPVar a
tv)= do
Maybe a
mr <- forall a. (IResource a, Typeable a) => DBRef a -> STM (Maybe a)
readDBRef DBRef a
dbref
case Maybe a
mr of
Just a
x -> do
forall a.
(IResource a, Typeable a) =>
[DBRef a] -> [Maybe a] -> STM ()
applyTriggers [DBRef a
dbref] [forall a. Maybe a
Nothing]
forall a. TVar a -> a -> STM ()
writeTVar TPVar a
tv forall a. Status a
DoNotExist
forall a. IO a -> STM a
safeIOToSTM forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b c. MVar b -> IO c -> IO c
criticalSection MVar Bool
saving forall a b. (a -> b) -> a -> b
$ forall a. IResource a => a -> IO ()
delResource a
x
Maybe a
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
onNothing :: Monad m => m (Maybe b) -> m b -> m b
onNothing :: forall (m :: * -> *) b. Monad m => m (Maybe b) -> m b -> m b
onNothing m (Maybe b)
io m b
onerr= do
Maybe b
my <- m (Maybe b)
io
case Maybe b
my of
Just b
y -> forall (m :: * -> *) a. Monad m => a -> m a
return b
y
Maybe b
Nothing -> m b
onerr
flushDBRef :: (IResource a, Typeable a) =>DBRef a -> STM()
flushDBRef :: forall a. (IResource a, Typeable a) => DBRef a -> STM ()
flushDBRef (DBRef String
_ TPVar a
tv)= forall a. TVar a -> a -> STM ()
writeTVar TPVar a
tv forall a. Status a
NotRead
flushKey :: String -> STM ()
flushKey :: String -> STM ()
flushKey String
key1= do
(HashTable RealWorld String CacheElem
cache, Integer
_) <- forall a. IO a -> STM a
unsafeIOToSTM forall a b. (a -> b) -> a -> b
$ forall a. IORef a -> IO a
readIORef Cache
refcache
Maybe CacheElem
c <- forall a. IO a -> STM a
unsafeIOToSTM forall a b. (a -> b) -> a -> b
$ forall (h :: * -> * -> * -> *) k v.
(HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> k -> IO (Maybe v)
H.lookup HashTable RealWorld String CacheElem
cache String
key1
case Maybe CacheElem
c of
Just (CacheElem Maybe (DBRef a)
_ Weak (DBRef a)
w) -> do
Maybe (DBRef a)
mr <- forall a. IO a -> STM a
unsafeIOToSTM forall a b. (a -> b) -> a -> b
$ forall v. Weak v -> IO (Maybe v)
deRefWeak Weak (DBRef a)
w
case Maybe (DBRef a)
mr of
Just (DBRef String
_ TPVar a
tv) -> forall a. TVar a -> a -> STM ()
writeTVar TPVar a
tv forall a. Status a
NotRead
Maybe (DBRef a)
Nothing -> forall a. IO a -> STM a
unsafeIOToSTM (forall v. Weak v -> IO ()
finalize Weak (DBRef a)
w) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String -> STM ()
flushKey String
key1
Maybe CacheElem
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
invalidateKey :: String -> STM ()
invalidateKey :: String -> STM ()
invalidateKey String
key1= do
(HashTable RealWorld String CacheElem
cache, Integer
_) <- forall a. IO a -> STM a
unsafeIOToSTM forall a b. (a -> b) -> a -> b
$ forall a. IORef a -> IO a
readIORef Cache
refcache
Maybe CacheElem
c <- forall a. IO a -> STM a
unsafeIOToSTM forall a b. (a -> b) -> a -> b
$ forall (h :: * -> * -> * -> *) k v.
(HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> k -> IO (Maybe v)
H.lookup HashTable RealWorld String CacheElem
cache String
key1
case Maybe CacheElem
c of
Just (CacheElem Maybe (DBRef a)
_ Weak (DBRef a)
w) -> do
Maybe (DBRef a)
mr <- forall a. IO a -> STM a
unsafeIOToSTM forall a b. (a -> b) -> a -> b
$ forall v. Weak v -> IO (Maybe v)
deRefWeak Weak (DBRef a)
w
case Maybe (DBRef a)
mr of
Just (DBRef String
_ TPVar a
tv) -> forall a. TVar a -> a -> STM ()
writeTVar TPVar a
tv forall a. Status a
DoNotExist
Maybe (DBRef a)
Nothing -> forall a. IO a -> STM a
unsafeIOToSTM (forall v. Weak v -> IO ()
finalize Weak (DBRef a)
w) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String -> STM ()
flushKey String
key1
Maybe CacheElem
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
flushAll :: STM ()
flushAll :: STM ()
flushAll = do
(HashTable RealWorld String CacheElem
cache, Integer
_) <- forall a. IO a -> STM a
unsafeIOToSTM forall a b. (a -> b) -> a -> b
$ forall a. IORef a -> IO a
readIORef Cache
refcache
[(String, CacheElem)]
elms <- forall a. IO a -> STM a
unsafeIOToSTM forall a b. (a -> b) -> a -> b
$ forall (h :: * -> * -> * -> *) k v.
(HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> IO [(k, v)]
H.toList HashTable RealWorld String CacheElem
cache
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall {a}. (a, CacheElem) -> STM ()
del [(String, CacheElem)]
elms
where
del :: (a, CacheElem) -> STM ()
del ( a
_ , CacheElem Maybe (DBRef a)
_ Weak (DBRef a)
w)= do
Maybe (DBRef a)
mr <- forall a. IO a -> STM a
unsafeIOToSTM forall a b. (a -> b) -> a -> b
$ forall v. Weak v -> IO (Maybe v)
deRefWeak Weak (DBRef a)
w
case Maybe (DBRef a)
mr of
Just (DBRef String
_ TPVar a
tv) -> forall a. TVar a -> a -> STM ()
writeTVar TPVar a
tv forall a. Status a
NotRead
Maybe (DBRef a)
Nothing -> forall a. IO a -> STM a
unsafeIOToSTM (forall v. Weak v -> IO ()
finalize Weak (DBRef a)
w)
withSTMResources :: (IResource a, Typeable a)=> [a]
-> ([Maybe a]-> Resources a x)
-> STM x
withSTMResources :: forall a x.
(IResource a, Typeable a) =>
[a] -> ([Maybe a] -> Resources a x) -> STM x
withSTMResources [a]
rs [Maybe a] -> Resources a x
f = do
(HashTable RealWorld String CacheElem
cache, Integer
_) <- forall a. IO a -> STM a
unsafeIOToSTM forall a b. (a -> b) -> a -> b
$ forall a. IORef a -> IO a
readIORef Cache
refcache
[Maybe (DBRef a)]
mtrs <- forall a.
(IResource a, Typeable a) =>
[a] -> Ht -> CheckTPVarFlags -> STM [Maybe (DBRef a)]
takeDBRefs [a]
rs HashTable RealWorld String CacheElem
cache CheckTPVarFlags
AddToHash
[Maybe a]
mrs <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall a.
(IResource a, Typeable a) =>
Maybe (DBRef a) -> STM (Maybe a)
mreadDBRef [Maybe (DBRef a)]
mtrs
case [Maybe a] -> Resources a x
f [Maybe a]
mrs of
Resources a x
Retry -> forall a. STM a
retry
Resources [a]
as [a]
ds x
r -> do
forall a.
(IResource a, Typeable a) =>
[DBRef a] -> [Maybe a] -> STM ()
applyTriggers (forall a b. (a -> b) -> [a] -> [b]
map (forall a. (Typeable a, IResource a) => String -> DBRef a
getDBRef forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. IResource a => a -> String
keyResource) [a]
ds) (forall a. a -> [a]
repeat (forall a. Maybe a
Nothing forall a. a -> a -> a
`asTypeOf` forall a. a -> Maybe a
Just (forall a. [a] -> a
head [a]
ds)))
forall a. IResource a => Ht -> [a] -> STM ()
delListFromHash HashTable RealWorld String CacheElem
cache [a]
ds
forall a. (IResource a, Typeable a) => [a] -> Ht -> STM ()
releaseTPVars [a]
as HashTable RealWorld String CacheElem
cache
forall a. IO a -> STM a
safeIOToSTM forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b c. MVar b -> IO c -> IO c
criticalSection MVar Bool
saving forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall a. IResource a => a -> IO ()
delResource [a]
ds
forall (m :: * -> *) a. Monad m => a -> m a
return x
r
where
mreadDBRef :: (IResource a, Typeable a) => Maybe (DBRef a) -> STM (Maybe a)
mreadDBRef :: forall a.
(IResource a, Typeable a) =>
Maybe (DBRef a) -> STM (Maybe a)
mreadDBRef (Just DBRef a
dbref) = forall a. (IResource a, Typeable a) => DBRef a -> STM (Maybe a)
readDBRef DBRef a
dbref
mreadDBRef Maybe (DBRef a)
Nothing = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
{-# INLINE withResource #-}
withResource:: (IResource a, Typeable a) => a -> (Maybe a-> a) -> IO ()
withResource :: forall a. (IResource a, Typeable a) => a -> (Maybe a -> a) -> IO ()
withResource a
r Maybe a -> a
f= forall a.
(IResource a, Typeable a) =>
[a] -> ([Maybe a] -> [a]) -> IO ()
withResources [a
r] (\[Maybe a
mr]-> [Maybe a -> a
f Maybe a
mr])
{-# INLINE withResources #-}
withResources:: (IResource a,Typeable a)=> [a]-> ([Maybe a]-> [a])-> IO ()
withResources :: forall a.
(IResource a, Typeable a) =>
[a] -> ([Maybe a] -> [a]) -> IO ()
withResources [a]
rs [Maybe a] -> [a]
f = forall a. STM a -> IO a
atomically forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall a x.
(IResource a, Typeable a) =>
[a] -> ([Maybe a] -> Resources a x) -> STM x
withSTMResources [a]
rs [Maybe a] -> Resources a ()
f1)
where
f1 :: [Maybe a] -> Resources a ()
f1 [Maybe a]
mrs =
let as :: [a]
as = [Maybe a] -> [a]
f [Maybe a]
mrs
in forall a b. [a] -> [a] -> b -> Resources a b
Resources [a]
as [] ()
{-# INLINE getResource #-}
getResource:: (IResource a, Typeable a)=>a-> IO (Maybe a)
getResource :: forall a. (IResource a, Typeable a) => a -> IO (Maybe a)
getResource a
r= do{[Maybe a]
mr<- forall a. (IResource a, Typeable a) => [a] -> IO [Maybe a]
getResources [a
r];forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$! forall a. [a] -> a
head [Maybe a]
mr}
{-# INLINE getResources #-}
getResources:: (IResource a, Typeable a)=>[a]-> IO [Maybe a]
getResources :: forall a. (IResource a, Typeable a) => [a] -> IO [Maybe a]
getResources [a]
rs= forall a. STM a -> IO a
atomically forall a b. (a -> b) -> a -> b
$ forall a x.
(IResource a, Typeable a) =>
[a] -> ([Maybe a] -> Resources a x) -> STM x
withSTMResources [a]
rs forall {b} {a}. b -> Resources a b
f1 where
f1 :: b -> Resources a b
f1 = forall a b. [a] -> [a] -> b -> Resources a b
Resources [] []
{-# INLINE deleteResource #-}
deleteResource :: (IResource a, Typeable a) => a -> IO ()
deleteResource :: forall a. (IResource a, Typeable a) => a -> IO ()
deleteResource a
r= forall a. (IResource a, Typeable a) => [a] -> IO ()
deleteResources [a
r]
{-# INLINE deleteResources #-}
deleteResources :: (IResource a, Typeable a) => [a] -> IO ()
deleteResources :: forall a. (IResource a, Typeable a) => [a] -> IO ()
deleteResources [a]
rs= forall a. STM a -> IO a
atomically forall a b. (a -> b) -> a -> b
$ forall a x.
(IResource a, Typeable a) =>
[a] -> ([Maybe a] -> Resources a x) -> STM x
withSTMResources [a]
rs forall {a}. [Maybe a] -> Resources a ()
f1 where
f1 :: [Maybe a] -> Resources a ()
f1 [Maybe a]
mrs = forall a. Resources a ()
resources {toDelete :: [a]
toDelete=forall a. [Maybe a] -> [a]
catMaybes [Maybe a]
mrs}
{-# INLINE takeDBRefs #-}
takeDBRefs :: (IResource a, Typeable a) => [a] -> Ht -> CheckTPVarFlags -> STM [Maybe (DBRef a)]
takeDBRefs :: forall a.
(IResource a, Typeable a) =>
[a] -> Ht -> CheckTPVarFlags -> STM [Maybe (DBRef a)]
takeDBRefs [a]
rs Ht
cache CheckTPVarFlags
addToHash= forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall a.
(IResource a, Typeable a) =>
Ht -> CheckTPVarFlags -> a -> STM (Maybe (DBRef a))
takeDBRef Ht
cache CheckTPVarFlags
addToHash) [a]
rs
{-# NOINLINE takeDBRef #-}
takeDBRef :: (IResource a, Typeable a) => Ht -> CheckTPVarFlags -> a -> STM(Maybe (DBRef a))
takeDBRef :: forall a.
(IResource a, Typeable a) =>
Ht -> CheckTPVarFlags -> a -> STM (Maybe (DBRef a))
takeDBRef Ht
cache CheckTPVarFlags
flags a
x =do
let keyr :: String
keyr= forall a. IResource a => a -> String
keyResource a
x
Maybe CacheElem
c <- forall a. IO a -> STM a
unsafeIOToSTM forall a b. (a -> b) -> a -> b
$ forall (h :: * -> * -> * -> *) k v.
(HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> k -> IO (Maybe v)
H.lookup Ht
cache String
keyr
case Maybe CacheElem
c of
Just (CacheElem Maybe (DBRef a)
_ Weak (DBRef a)
w) -> do
Maybe (DBRef a)
mr <- forall a. IO a -> STM a
unsafeIOToSTM forall a b. (a -> b) -> a -> b
$ forall v. Weak v -> IO (Maybe v)
deRefWeak Weak (DBRef a)
w
case Maybe (DBRef a)
mr of
Just DBRef a
dbref -> forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$! forall a1 a2. (Typeable a1, Typeable a2) => a1 -> a2
castErr DBRef a
dbref
Maybe (DBRef a)
Nothing -> forall a. IO a -> STM a
unsafeIOToSTM (forall v. Weak v -> IO ()
finalize Weak (DBRef a)
w) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a.
(IResource a, Typeable a) =>
Ht -> CheckTPVarFlags -> a -> STM (Maybe (DBRef a))
takeDBRef Ht
cache CheckTPVarFlags
flags a
x
Maybe CacheElem
Nothing ->
forall a. IO a -> STM a
safeIOToSTM forall a b. (a -> b) -> a -> b
$ forall {h :: * -> * -> * -> *}.
HashTable h =>
CheckTPVarFlags
-> h RealWorld String CacheElem -> String -> IO (Maybe (DBRef a))
readToCache CheckTPVarFlags
flags Ht
cache String
keyr
where
readToCache :: CheckTPVarFlags
-> h RealWorld String CacheElem -> String -> IO (Maybe (DBRef a))
readToCache CheckTPVarFlags
flags1 h RealWorld String CacheElem
cache1 String
key1= do
Maybe a
mr <- forall a. IResource a => a -> IO (Maybe a)
readResource a
x
case Maybe a
mr of
Maybe a
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
Just a
r2 -> do
Integer
ti <- IO Integer
timeInteger
TVar (Status (Elem a))
tvr <- forall a. a -> IO (TVar a)
newTVarIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Status a
Exist forall a b. (a -> b) -> a -> b
$ forall a. a -> Integer -> Integer -> Elem a
Elem a
r2 Integer
ti (-Integer
1)
case CheckTPVarFlags
flags1 of
CheckTPVarFlags
NoAddToHash -> forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. String -> TPVar a -> DBRef a
DBRef String
key1 TVar (Status (Elem a))
tvr
CheckTPVarFlags
AddToHash -> do
DBRef a
dbref <- forall a. a -> IO a
evaluate forall a b. (a -> b) -> a -> b
$ forall a. String -> TPVar a -> DBRef a
DBRef String
key1 TVar (Status (Elem a))
tvr
Weak (DBRef a)
w <- forall k. k -> Maybe (IO ()) -> IO (Weak k)
mkWeakPtr DBRef a
dbref forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. (IResource a, Typeable a) => DBRef a -> IO ()
fixToCache DBRef a
dbref
forall (h :: * -> * -> * -> *) k v.
(HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> k -> v -> IO ()
H.insert h RealWorld String CacheElem
cache1 String
key1 (forall a.
(IResource a, Typeable a) =>
Maybe (DBRef a) -> Weak (DBRef a) -> CacheElem
CacheElem (forall a. a -> Maybe a
Just DBRef a
dbref) Weak (DBRef a)
w)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just DBRef a
dbref
timeInteger :: IO Integer
timeInteger :: IO Integer
timeInteger= do TOD Integer
t Integer
_ <- IO ClockTime
getClockTime
forall (m :: * -> *) a. Monad m => a -> m a
return Integer
t
releaseTPVars :: (IResource a,Typeable a)=> [a] -> Ht -> STM ()
releaseTPVars :: forall a. (IResource a, Typeable a) => [a] -> Ht -> STM ()
releaseTPVars [a]
rs Ht
cache = forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (forall a. (IResource a, Typeable a) => Ht -> a -> STM ()
releaseTPVar Ht
cache) [a]
rs
releaseTPVar :: (IResource a,Typeable a)=> Ht -> a -> STM ()
releaseTPVar :: forall a. (IResource a, Typeable a) => Ht -> a -> STM ()
releaseTPVar Ht
cache a
r =do
Maybe CacheElem
c <- forall a. IO a -> STM a
unsafeIOToSTM forall a b. (a -> b) -> a -> b
$ forall (h :: * -> * -> * -> *) k v.
(HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> k -> IO (Maybe v)
H.lookup Ht
cache String
keyr
case Maybe CacheElem
c of
Just (CacheElem Maybe (DBRef a)
_ Weak (DBRef a)
w) -> do
Maybe (DBRef a)
mr <- forall a. IO a -> STM a
unsafeIOToSTM forall a b. (a -> b) -> a -> b
$ forall v. Weak v -> IO (Maybe v)
deRefWeak Weak (DBRef a)
w
case Maybe (DBRef a)
mr of
Maybe (DBRef a)
Nothing -> forall a. IO a -> STM a
unsafeIOToSTM (forall v. Weak v -> IO ()
finalize Weak (DBRef a)
w) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. (IResource a, Typeable a) => Ht -> a -> STM ()
releaseTPVar Ht
cache a
r
Just dbref :: DBRef a
dbref@(DBRef String
_ TPVar a
tv) -> do
forall a.
(IResource a, Typeable a) =>
[DBRef a] -> [Maybe a] -> STM ()
applyTriggers [DBRef a
dbref] [forall a. a -> Maybe a
Just (forall a1 a2. (Typeable a1, Typeable a2) => a1 -> a2
castErr a
r)]
Integer
t <- forall a. IO a -> STM a
unsafeIOToSTM IO Integer
timeInteger
forall a. TVar a -> a -> STM ()
writeTVar TPVar a
tv forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Status a
Exist forall a b. (a -> b) -> a -> b
$ forall a. a -> Integer -> Integer -> Elem a
Elem (forall a1 a2. (Typeable a1, Typeable a2) => a1 -> a2
castErr a
r) Integer
t Integer
t
Maybe CacheElem
Nothing -> do
Integer
ti <- forall a. IO a -> STM a
unsafeIOToSTM IO Integer
timeInteger
TVar (Status (Elem a))
tvr <- forall a. a -> STM (TVar a)
newTVar forall a. Status a
NotRead
DBRef a
dbref <- forall a. IO a -> STM a
unsafeIOToSTM forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> IO a
evaluate forall a b. (a -> b) -> a -> b
$ forall a. String -> TPVar a -> DBRef a
DBRef String
keyr TVar (Status (Elem a))
tvr
forall a.
(IResource a, Typeable a) =>
[DBRef a] -> [Maybe a] -> STM ()
applyTriggers [DBRef a
dbref] [forall a. a -> Maybe a
Just a
r]
forall a. TVar a -> a -> STM ()
writeTVar TVar (Status (Elem a))
tvr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Status a
Exist forall a b. (a -> b) -> a -> b
$ forall a. a -> Integer -> Integer -> Elem a
Elem a
r Integer
ti Integer
ti
Weak (DBRef a)
w <- forall a. IO a -> STM a
unsafeIOToSTM forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k. k -> Maybe (IO ()) -> IO (Weak k)
mkWeakPtr DBRef a
dbref forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. (IResource a, Typeable a) => DBRef a -> IO ()
fixToCache DBRef a
dbref
forall a. IO a -> STM a
unsafeIOToSTM forall a b. (a -> b) -> a -> b
$ forall (h :: * -> * -> * -> *) k v.
(HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> k -> v -> IO ()
H.insert Ht
cache String
keyr (forall a.
(IResource a, Typeable a) =>
Maybe (DBRef a) -> Weak (DBRef a) -> CacheElem
CacheElem (forall a. a -> Maybe a
Just DBRef a
dbref) Weak (DBRef a)
w)
forall (m :: * -> *) a. Monad m => a -> m a
return ()
where keyr :: String
keyr= forall a. IResource a => a -> String
keyResource a
r
delListFromHash :: IResource a => Ht -> [a] -> STM ()
delListFromHash :: forall a. IResource a => Ht -> [a] -> STM ()
delListFromHash Ht
cache= forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall a. IResource a => a -> STM ()
del
where
del :: IResource a => a -> STM ()
del :: forall a. IResource a => a -> STM ()
del a
x= do
let key1 :: String
key1= forall a. IResource a => a -> String
keyResource a
x
Maybe CacheElem
mr <- forall a. IO a -> STM a
unsafeIOToSTM forall a b. (a -> b) -> a -> b
$ forall (h :: * -> * -> * -> *) k v.
(HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> k -> IO (Maybe v)
H.lookup Ht
cache String
key1
case Maybe CacheElem
mr of
Maybe CacheElem
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just (CacheElem Maybe (DBRef a)
_ Weak (DBRef a)
w) -> do
Maybe (DBRef a)
mr1 <- forall a. IO a -> STM a
unsafeIOToSTM forall a b. (a -> b) -> a -> b
$ forall v. Weak v -> IO (Maybe v)
deRefWeak Weak (DBRef a)
w
case Maybe (DBRef a)
mr1 of
Just (DBRef String
_ TPVar a
tv) ->
forall a. TVar a -> a -> STM ()
writeTVar TPVar a
tv forall a. Status a
DoNotExist
Maybe (DBRef a)
Nothing ->
forall a. IO a -> STM a
unsafeIOToSTM (forall v. Weak v -> IO ()
finalize Weak (DBRef a)
w) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. IResource a => a -> STM ()
del a
x
clearSyncCacheProc ::
Int
-> (Integer -> Integer-> Integer-> Bool)
-> Int
-> IO ThreadId
clearSyncCacheProc :: Int
-> (Integer -> Integer -> Integer -> Bool) -> Int -> IO ThreadId
clearSyncCacheProc Int
time Integer -> Integer -> Integer -> Bool
check1 Int
sizeObjects= IO () -> IO ThreadId
forkIO forall {b}. IO b
clear
where
clear :: IO b
clear = do
Int -> IO ()
threadDelay forall a b. (a -> b) -> a -> b
$ Int
time forall a. Num a => a -> a -> a
* Int
1000000
forall e a. Exception e => (e -> IO a) -> IO a -> IO a
handle ( \ (SomeException
e :: SomeException)-> Handle -> String -> IO ()
hPutStr Handle
stderr (forall a. Show a => a -> String
show SomeException
e) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> IO b
clear ) forall a b. (a -> b) -> a -> b
$ do
(Integer -> Integer -> Integer -> Bool) -> Int -> IO ()
clearSyncCache Integer -> Integer -> Integer -> Bool
check1 Int
sizeObjects
IO b
clear
criticalSection :: MVar b -> IO c -> IO c
criticalSection :: forall b c. MVar b -> IO c -> IO c
criticalSection MVar b
mv IO c
f= forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket
(forall a. MVar a -> IO a
takeMVar MVar b
mv)
(forall a. MVar a -> a -> IO ()
putMVar MVar b
mv)
forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> a
const IO c
f
syncCache :: IO ()
syncCache :: IO ()
syncCache = forall b c. MVar b -> IO c -> IO c
criticalSection MVar Bool
saving forall a b. (a -> b) -> a -> b
$ do
(HashTable RealWorld String CacheElem
cache,Integer
lastSync) <- forall a. IORef a -> IO a
readIORef Cache
refcache
Integer
t2<- IO Integer
timeInteger
[(String, CacheElem)]
elems <- forall (h :: * -> * -> * -> *) k v.
(HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> IO [(k, v)]
H.toList HashTable RealWorld String CacheElem
cache
([Filtered]
tosave,[CacheElem]
_,Int
_) <- forall a. STM a -> IO a
atomically forall a b. (a -> b) -> a -> b
$ forall a.
[(a, CacheElem)] -> Integer -> STM ([Filtered], [CacheElem], Int)
extract [(String, CacheElem)]
elems Integer
lastSync
forall (t :: * -> *). Foldable t => t Filtered -> IO ()
save [Filtered]
tosave
forall a. IORef a -> a -> IO ()
writeIORef Cache
refcache (HashTable RealWorld String CacheElem
cache, Integer
t2)
data SyncMode= Synchronous
| Asynchronous
{SyncMode -> Int
frequency :: Int
,SyncMode -> Integer -> Integer -> Integer -> Bool
check :: Integer-> Integer-> Integer-> Bool
,SyncMode -> Int
cacheSize :: Int
}
| SyncManual
{-# NOINLINE tvSyncWrite #-}
tvSyncWrite :: IORef (SyncMode, Maybe a)
tvSyncWrite :: forall a. IORef (SyncMode, Maybe a)
tvSyncWrite= forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ forall a. a -> IO (IORef a)
newIORef (SyncMode
Synchronous, forall a. Maybe a
Nothing)
syncWrite:: SyncMode -> IO()
syncWrite :: SyncMode -> IO ()
syncWrite SyncMode
mode = do
(SyncMode
_, Maybe ThreadId
thread) <- forall a. IORef a -> IO a
readIORef forall a. IORef (SyncMode, Maybe a)
tvSyncWrite
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ Maybe ThreadId
thread ThreadId -> IO ()
killThread
case SyncMode
mode of
SyncMode
Synchronous -> IO ()
modeWrite
SyncMode
SyncManual -> IO ()
modeWrite
Asynchronous Int
time Integer -> Integer -> Integer -> Bool
check1 Int
maxsize -> do
()
th <- forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ Int
-> (Integer -> Integer -> Integer -> Bool) -> Int -> IO ThreadId
clearSyncCacheProc Int
time Integer -> Integer -> Integer -> Bool
check1 Int
maxsize
forall a. IORef a -> a -> IO ()
writeIORef forall a. IORef (SyncMode, Maybe a)
tvSyncWrite (SyncMode
mode, forall a. a -> Maybe a
Just ()
th)
where
modeWrite :: IO ()
modeWrite = forall a. IORef a -> a -> IO ()
writeIORef forall a. IORef (SyncMode, Maybe a)
tvSyncWrite (SyncMode
mode, forall a. Maybe a
Nothing)
atomicallySync :: STM a -> IO a
atomicallySync :: forall a. STM a -> IO a
atomicallySync STM a
proc=do
a
r <- forall a. STM a -> IO a
atomically STM a
proc
IO ()
sync
forall (m :: * -> *) a. Monad m => a -> m a
return a
r
where
sync :: IO ()
sync= do
(SyncMode
savetype,Maybe Any
_) <- forall a. IORef a -> IO a
readIORef forall a. IORef (SyncMode, Maybe a)
tvSyncWrite
case SyncMode
savetype of
SyncMode
Synchronous -> IO ()
syncCache
SyncMode
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
clearSyncCache :: (Integer -> Integer-> Integer-> Bool)-> Int -> IO ()
clearSyncCache :: (Integer -> Integer -> Integer -> Bool) -> Int -> IO ()
clearSyncCache Integer -> Integer -> Integer -> Bool
check1 Int
sizeObjects= forall b c. MVar b -> IO c -> IO c
criticalSection MVar Bool
saving forall a b. (a -> b) -> a -> b
$ do
(HashTable RealWorld String CacheElem
cache,Integer
lastSync) <- forall a. IORef a -> IO a
readIORef Cache
refcache
Integer
t <- IO Integer
timeInteger
[(String, CacheElem)]
elems <- forall (h :: * -> * -> * -> *) k v.
(HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> IO [(k, v)]
H.toList HashTable RealWorld String CacheElem
cache
([Filtered]
tosave, [CacheElem]
elems1, Int
size) <- forall a. STM a -> IO a
atomically forall a b. (a -> b) -> a -> b
$ forall a.
[(a, CacheElem)] -> Integer -> STM ([Filtered], [CacheElem], Int)
extract [(String, CacheElem)]
elems Integer
lastSync
forall (t :: * -> *). Foldable t => t Filtered -> IO ()
save [Filtered]
tosave
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
size forall a. Ord a => a -> a -> Bool
> Int
sizeObjects) forall a b. (a -> b) -> a -> b
$ IO () -> IO ThreadId
forkIO (forall {t :: * -> *} {h :: * -> * -> * -> *}.
(Foldable t, HashTable h) =>
Integer
-> h RealWorld String CacheElem -> Integer -> t CacheElem -> IO ()
filtercache Integer
t HashTable RealWorld String CacheElem
cache Integer
lastSync [CacheElem]
elems1) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> IO ()
performGC
forall a. IORef a -> a -> IO ()
writeIORef Cache
refcache (HashTable RealWorld String CacheElem
cache, Integer
t)
where
filtercache :: Integer
-> h RealWorld String CacheElem -> Integer -> t CacheElem -> IO ()
filtercache Integer
t h RealWorld String CacheElem
cache Integer
lastSync = forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ CacheElem -> IO ()
filter1
where
filter1 :: CacheElem -> IO ()
filter1 (CacheElem Maybe (DBRef a)
Nothing Weak (DBRef a)
_)= forall (m :: * -> *) a. Monad m => a -> m a
return()
filter1 (CacheElem (Just (DBRef String
key1 TPVar a
_)) Weak (DBRef a)
w) = do
Maybe (DBRef a)
mr <- forall v. Weak v -> IO (Maybe v)
deRefWeak Weak (DBRef a)
w
case Maybe (DBRef a)
mr of
Maybe (DBRef a)
Nothing -> forall v. Weak v -> IO ()
finalize Weak (DBRef a)
w
Just (DBRef String
_ TPVar a
tv) -> forall a. STM a -> IO a
atomically forall a b. (a -> b) -> a -> b
$ do
Status (Elem a)
r <- forall a. TVar a -> STM a
readTVar TPVar a
tv
case Status (Elem a)
r of
Exist (Elem a
_ Integer
lastAccess Integer
_ ) ->
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Integer -> Integer -> Integer -> Bool
check1 Integer
t Integer
lastAccess Integer
lastSync) forall a b. (a -> b) -> a -> b
$ do
forall a. IO a -> STM a
unsafeIOToSTM forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (h :: * -> * -> * -> *) k v.
(HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> k -> v -> IO ()
H.insert h RealWorld String CacheElem
cache String
key1 forall a b. (a -> b) -> a -> b
$ forall a.
(IResource a, Typeable a) =>
Maybe (DBRef a) -> Weak (DBRef a) -> CacheElem
CacheElem forall a. Maybe a
Nothing Weak (DBRef a)
w
forall a. TVar a -> a -> STM ()
writeTVar TPVar a
tv forall a. Status a
NotRead
Status (Elem a)
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return()
defaultCheck
:: Integer
-> Integer
-> Integer
-> Bool
defaultCheck :: Integer -> Integer -> Integer -> Bool
defaultCheck Integer
now Integer
lastAccess Integer
lastSync
| Integer
lastAccess forall a. Ord a => a -> a -> Bool
> Integer
halftime = Bool
False
| Bool
otherwise = Bool
True
where
halftime :: Integer
halftime= Integer
nowforall a. Num a => a -> a -> a
- (Integer
nowforall a. Num a => a -> a -> a
-Integer
lastSync) forall a. Integral a => a -> a -> a
`div` Integer
2
{-# NOINLINE refConditions #-}
refConditions :: IORef (IO (), IO ())
refConditions :: IORef (IO (), IO ())
refConditions= forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ forall a. a -> IO (IORef a)
newIORef (forall (m :: * -> *) a. Monad m => a -> m a
return(), forall (m :: * -> *) a. Monad m => a -> m a
return())
setConditions :: IO() -> IO() -> IO()
setConditions :: IO () -> IO () -> IO ()
setConditions IO ()
pre IO ()
post= forall a. IORef a -> a -> IO ()
writeIORef IORef (IO (), IO ())
refConditions (IO ()
pre, IO ()
post)
{-# NOINLINE saving #-}
saving :: MVar Bool
saving :: MVar Bool
saving= forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ forall a. a -> IO (MVar a)
newMVar Bool
False
save :: Foldable t => t Filtered -> IO ()
save :: forall (t :: * -> *). Foldable t => t Filtered -> IO ()
save t Filtered
tosave = do
(IO ()
pre, IO ()
post) <- forall a. IORef a -> IO a
readIORef IORef (IO (), IO ())
refConditions
IO ()
pre
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (\(Filtered a
x) -> forall a. IResource a => a -> IO ()
writeResource a
x) t Filtered
tosave
IO ()
post
data Filtered= forall a.(IResource a)=> Filtered a
extract :: [(a, CacheElem)] -> Integer -> STM ([Filtered], [CacheElem], Int)
[(a, CacheElem)]
elems Integer
lastSave= forall {c} {a}.
Num c =>
[Filtered]
-> [CacheElem]
-> c
-> [(a, CacheElem)]
-> STM ([Filtered], [CacheElem], c)
filter1 [] [] (Int
0:: Int) [(a, CacheElem)]
elems
where
filter1 :: [Filtered]
-> [CacheElem]
-> c
-> [(a, CacheElem)]
-> STM ([Filtered], [CacheElem], c)
filter1 [Filtered]
sav [CacheElem]
val c
n []= forall (m :: * -> *) a. Monad m => a -> m a
return ([Filtered]
sav, [CacheElem]
val, c
n)
filter1 [Filtered]
sav [CacheElem]
val c
n ((a
_, ch :: CacheElem
ch@(CacheElem Maybe (DBRef a)
mybe Weak (DBRef a)
w)):[(a, CacheElem)]
rest)= do
Maybe (DBRef a)
mr <- forall a. IO a -> STM a
unsafeIOToSTM forall a b. (a -> b) -> a -> b
$ forall v. Weak v -> IO (Maybe v)
deRefWeak Weak (DBRef a)
w
case Maybe (DBRef a)
mr of
Maybe (DBRef a)
Nothing -> forall a. IO a -> STM a
unsafeIOToSTM (forall v. Weak v -> IO ()
finalize Weak (DBRef a)
w) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [Filtered]
-> [CacheElem]
-> c
-> [(a, CacheElem)]
-> STM ([Filtered], [CacheElem], c)
filter1 [Filtered]
sav [CacheElem]
val c
n [(a, CacheElem)]
rest
Just (DBRef String
_ TPVar a
tvr) ->
let tofilter :: [CacheElem]
tofilter = case Maybe (DBRef a)
mybe of
Just DBRef a
_ -> CacheElem
chforall a. a -> [a] -> [a]
:[CacheElem]
val
Maybe (DBRef a)
Nothing -> [CacheElem]
val
in do
Status (Elem a)
r <- forall a. TVar a -> STM a
readTVar TPVar a
tvr
case Status (Elem a)
r of
Exist (Elem a
r1 Integer
_ Integer
modTime) ->
if Integer
modTime forall a. Ord a => a -> a -> Bool
>= Integer
lastSave
then [Filtered]
-> [CacheElem]
-> c
-> [(a, CacheElem)]
-> STM ([Filtered], [CacheElem], c)
filter1 (forall a. IResource a => a -> Filtered
Filtered a
r1forall a. a -> [a] -> [a]
:[Filtered]
sav) [CacheElem]
tofilter (c
nforall a. Num a => a -> a -> a
+c
1) [(a, CacheElem)]
rest
else [Filtered]
-> [CacheElem]
-> c
-> [(a, CacheElem)]
-> STM ([Filtered], [CacheElem], c)
filter1 [Filtered]
sav [CacheElem]
tofilter (c
nforall a. Num a => a -> a -> a
+c
1) [(a, CacheElem)]
rest
Status (Elem a)
_ -> [Filtered]
-> [CacheElem]
-> c
-> [(a, CacheElem)]
-> STM ([Filtered], [CacheElem], c)
filter1 [Filtered]
sav [CacheElem]
tofilter (c
nforall a. Num a => a -> a -> a
+c
1) [(a, CacheElem)]
rest
safeIOToSTM :: IO a -> STM a
safeIOToSTM :: forall a. IO a -> STM a
safeIOToSTM IO a
req= forall a. IO a -> STM a
unsafeIOToSTM forall a b. (a -> b) -> a -> b
$ do
MVar (Either SomeException a)
tv <- forall a. IO (MVar a)
newEmptyMVar
ThreadId
_ <- IO () -> IO ThreadId
forkIO forall a b. (a -> b) -> a -> b
$ (IO a
req forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a. MVar a -> a -> IO ()
putMVar MVar (Either SomeException a)
tv forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. b -> Either a b
Right)
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`Control.Exception.catch`
(\(SomeException
e :: SomeException) -> forall a. MVar a -> a -> IO ()
putMVar MVar (Either SomeException a)
tv forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left SomeException
e )
Either SomeException a
r <- forall a. MVar a -> IO a
takeMVar MVar (Either SomeException a)
tv
case Either SomeException a
r of
Right a
x -> forall (m :: * -> *) a. Monad m => a -> m a
return a
x
Left SomeException
e -> forall a e. Exception e => e -> a
throw SomeException
e