Saturday, November 17, 2007

New version of the Transactiona Cache (not tested)

NOTE: last version download at: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/TCache I created a new version of the Transactional Cache  See the original post  where I describe the idea. (download this version ). Some interesting additions are:
  • Default persistence in files (both strict file reads and fail safe reads/writes are needed, because reads and writes can collide).
  • Direct handling of TVars with full atomic semantic without loosing transparent persistence (getTVars)
  • No repeated hashtable lookups in case of atomic rollbacks
  • insertResources
  • readFileStrict - to be used for instantiate custom persistence in files.
  • Not only addings but also deletes of objects within single atomic operations. (withResourcesID)

Also, a minimal description of existing primitives has been added.

This is the header:

module TCache (

IResource(..)              -- class interface to be instantiated by the user
,DefaultPersistResource(..) --instance of IResource with default definitions, except defkeyResource
,Serializable(..)          --instances of DefaultPersistResource must be instances of Serializable as well
,Operation (Insert,Delete) -- data definition used to communicate object Inserts and Deletes to the cache

,Cache            -- :: IORef (Ht a,Int, Integer)     --The cache definition

,withResourcesID  -- :: (IResource a)=> [a]->         --list of resources to be extracted for the user function
                 --    ([Maybe a]->[Operation a])    --user function that get the retrieved resources
         --    ->IO ()                       --and return a list of  objects to be inserted/modified or deleted

,withResources   -- :: (IResource a)=> [a]            --list of resources to be retrieve
                 --   ->([Maybe a]->[a])             ----function that get the retrieved resources
                 --   ->IO ()                        --and return a list of  objects to be inserted/modified

,withResource    -- :: (IResource a)=> a              --same as withResources , but for one only object
                 --   ->([Maybe a]->a)               --
                 --   ->IO ()                        --

,insertResources  -- :: (IResource a)=> [a] ->IO ()   -- create resources in the cache. if there are resources with
                                                     -- the same key, they will be updated.

-- getMVars give  the transactional variables (TVar´s) to be handled directly by the user. This allows  the full
-- semantics of "atomic" blocks. Because the TVars are referenced also by the hashtable, the resources inside these TVars
-- are saved to disk,transparently for the user, on every sync. Also, they are not deleted from the cache until released.
-- getMVars put a high value in the access time an modif. time to avoid the swap process to  delete from memory
-- getMVars is also useful when the same resources are frequently accessed. This avoid frequent hashtable lookups.

,getTVars        -- :: (IResource a)=> [a]           -- the list of resources to be retrieved
                  --    -> IO [Maybe (TVar a)]        -- The Transactional variables (See Data.TVar documentation)

-- releaseMVars allows the release of the resources taken by takeMVars so that them can be swapped to disk if needed.
,releaseTVars     -- :: (IResource a)=> [a]-> IO()

,getResources    -- :: (IResource a)=>[a]             --resources [a] are read from cache and returned
                 --   -> IO [Maybe a]   

,getResource     -- :: :: (IResource a)=>a            --to retrieve one object instead of a list
                 --   -> IO [Maybe a]   

,deleteResources -- :: (IResource a)=>[a]-> IO()      -- delete the list of resources from cache and from persistent storage
,deleteResource  -- :: (IResource a)=>a-> IO()        -- delete the  resource from cache and from persistent storage
--cache handling

,refcache        -- :: Cache a                        --the reference to the cache (see data definition below)

,syncCache       -- :: (IResource a) =>Cache a -> IO() --force the atomic write of all the cache objects into permanent storage
                                                       --useful for termination

--start the thread that clean and writes on the persistent storage trough syncCache
,clearSyncCacheProc  -- :: (IResource a) =>Cache a       --The cache reference                        
                     --   -> Int                         --number of seconds betwen checks
                     --   -> (Integer->Integer-> Bool)   --The user-defined check-for-cleanup-from-cache for each object
                                                         --(when True, the object is removed from cache)
                     --   -> Int                         --The max number of objects in the cache, if more, the cleanup start
                     --   -> >IO ThreadId                --Identifier of the thread created

-- the default check procedure
,defaultCheck    -- :: Integer                          --last access time for a given object
                 --   ->Integer                        --last cache syncronization (with the persisten storage)
                 --   ->Bool                           --return true for all the elems not accesed since  
                                                       --half the time between now and the last sync
                                                     
-- auxiliary
,readFileStrict  -- :: String -> IO String            -- Strict file read, needed for persistence trough files