#      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ None "Resources data definition used by withSTMResources +resources to be inserted back in the cache Bresources to be deleted from the cache and from permanent storage result to be returned forces a retry /Must be defined for every object to be cached. >Implements the database access and marshalling of the object. h while the database access must be strict, the marshaling must be lazy if, as is often the case, 9 some parts of the object are not really accesed. M If the object contains DBRefs, this avoids unnecesary cache lookups. % This method is called inside  blocks.  Since STM transactions retry, readResourceByKey may be called twice in strange situations. So it must be idempotent, not only in the result but also in the effect in the database - . However, because it is executed by  safeIOToSTM9 it is guaranteed that the execution is not interrupted. 7To write into persistent storage. It must be strict. # Since STM transactions may retry,  writeResourceT must be idempotent, not only in the result but also in the effect in the database. & . However, because it is executed by  safeIOToSTM9 it is guaranteed that the execution is not interrupted. E All the new obbects are writeen to the database on synchromization, ' so writeResource must not autocommit. 9 Commit code must be located in the postcondition. (see  setConditions) E Since there is no provision for rollback from failure in writing to  persistent storage,   must retry until success. GDelete the resource. It is called syncronously. So it must tocommit Empty resources: resources= Resources [] [] ()  must be defined      None <a persist mechanism has to implement these three primitives  (! is the default file persistence delete read by key. It must be strict write. It must be strict WSerialize is an alternative to the IResource class for defining persistence in TCache. 1The deserialization must be as lazy as possible.  serialization/7deserialization are not performance critical in TCache >Read, Show, instances are implicit instances of Serializable   serialize = show  deserialize= read "Since write and read to disk of to/(from the cache are not be very frequent 2The performance of serialization is not critical. DIndexable is an utility class used to derive instances of IResource  Example:  8data Person= Person{ pname :: String, cars :: [DBRef Car]"} deriving (Show, Read, Typeable) Zdata Car= Car{owner :: DBRef Person , cname:: String} deriving (Show, Read, Eq, Typeable) &Since Person and Car are instances of  ans , by defining the  instance Dwill implicitly define the IResource instance for file persistence:  7instance Indexable Person where key Person{pname=n} = "Person " ++ n 1instance Indexable Car where key Car{cname= n} = "Car " ++ n (PImplements default persistence of objects in files with their keys as filenames *-Set the default persistence mechanism of all  serializable objetcts. By default it is ( @this statement must be the first one before any other in TCache 4;Strict read from file, needed for default file persistence )defaultPersist if Nothing -additional extension for default file paths. _ IMPORTANT: defPath must depend on the datatype, not the value (must be constant). Default is  .tcachedata/  !"#$%&'()*+,-./01234% !"#$%&'()*+,-./01234%&%!$#" '()*+,-./01234 !$#"%&'()*+,-./01234None54Add an user defined trigger to the list of triggers ^Trriggers are called just before an object of the given type is created, modified or deleted. DThe DBRef to the object and the new value is passed to the trigger. HThe called trigger function has two parameters: the DBRef being accesed 9(which still contains the old value), and the new value. 7If the DBRef is being deleted, the second parameter is . @if the DBRef contains Nothing, then the object is being created 6*internally called when a DBRef is modifieddeletedcreated 56  !"#$56  !$#"5656None#8use U to write the state :1number of seconds between saves when asyncronous ;?The user-defined check-for-cleanup-from-cache for each object. Y is an example <size of the cache when async =%sync state to permanent storage when W is invoked ?fSet the cache. this is useful for hot loaded modules that will update an existing cache. Experimental (The cache holder. stablished by default @"Creates a new cache. Experimental AEReturn the total number of DBRefs in the cache. For debug purposes. P This does not count the number of objects in the cache since many of the DBRef + may not have the pointed object loaded. It's O(n). BEReturn the reference value. If it is not in the cache, it is fetched  from the database. CWrite in the reference a value M The new key must be the same than the old key of the previous object stored  otherwise, an error law of key conservation broken will be raised ^WARNING: the value to be written in the DBRef must be fully evaluated. Delayed evaluations at ? serialization time can cause inconsistencies in the database. + In future releases this will be enforced. D5Return the key of the object pointed to by the DBRef EdGet the reference to the object in the cache. if it does not exist, the reference is created empty.  Every execution of E0 returns the same unique reference to this key, X so it can be safely considered pure. This is a property useful because deserialization & of objects with unused embedded DBRef')s do not need to marshall them eagerly. C Tbis also avoid unnecesary cache lookups of the pointed objects. FACreate the object passed as parameter (if it does not exist) and )-- return its reference in the IO monad. G-- If an object with the same key already exists, it is returned as is 8-- If not, the reference is created with the new value. *-- If you like to update in any case, use E and C combined <newDBRefIO :: (IResource a,Typeable a) => a -> IO (DBRef a) newDBRefIO x= do  let key = keyResource x  mdbref <- mDBRefIO key  case mdbref of  Right dbref -> return dbref Left cache -> do  tv<- newTVarIO DoNotExist  let dbref= DBRef key tv  w <-- mkWeakPtr dbref . Just $ fixToCache dbref . H.update cache key (CacheElem Nothing w)  t <- timeInteger  atomically $ do  applyTriggers [dbref] [Just x] --debug (before ++key) * writeTVar tv . Exist $ Elem x t t  return dbref ACreate the object passed as parameter (if it does not exist) and ( return its reference in the STM monad. E If an object with the same key already exists, it is returned as is 6 If not, the reference is created with the new value. ( If you like to update in any case, use E and C combined E if you need to create the reference and the reference content, use F GJDelete the content of the DBRef form the cache and from permanent storage H7Handles Nothing cases in a simpler way than runMaybeT. , it is used in infix notation. for example:  result <- readDBRef ref ` onNothing` error (" Not found "++ keyObjDBRef ref)or result <- readDBRef ref ` onNothing` return someDefaultValueIADeletes the pointed object from the cache, not the database (see G) N useful for cache invalidation when the database is modified by other process J%flush the element with the given key K-label the object as not existent in database Ldrops the entire cache. MyThis is the main function for the *Resource(s) calls. All the rest derive from it. The results are kept in the STM monad G so it can be part of a larger STM transaction involving other DBRefs.  The J register returned by the user-defined function is interpreted as such:  *: the content of this field will be added/updated to the cache  V: the content of this field will be removed from the cache and from permanent storage  0: the content of this field will be returned by M kWARNING: To catch evaluations errors at the right place, the values to be written must be fully evaluated. ` Errors in delayed evaluations at serialization time can cause inconsistencies in the database. N'Update of a single object in the cache withResource r f= O [r] ([mr]-> [f mr])OTo atomically add/!modify many objects in the cache # withResources rs f= atomically $ MD rs f1 >> return() where f1 mrs= let as= f mrs in Resources as [] ()P#To read a resource from the cache. getResource r= do{mr<- Q [r];return $! head mr}Q9To read a list of resources from the cache if they exist | getResources rs= atomically $ M" rs f1 where f1 mrs= Resources [] [] mrs R>Delete the resource from cache and from persistent storage.  deleteResource r= S [r]SEDelete the list of resources from cache and from persistent storage. # deleteResources rs= atomically $ M# rs f1 where f1 mrs = Resources [] (catMaybes mrs) ()T(Start the thread that periodically call X0 to clean and writes on the persistent storage. ! it is indirecly set by means of V?, since it is more higuer level. I recommend to use the latter  Otherwise, U or X or W: must be invoked explicitly or no persistence will exist. , Cache writes allways save a coherent state UbForce the atomic write of all cached objects modified since the last save into permanent storage. ` Cache writes allways save a coherent state. As allways, only the modified objects are written. VESpecify the cache synchronization policy with permanent storage. See 7 for details W`Perform a synchronization of the cache with permanent storage once executed the STM transaction  when V policy is = X&Saves the unsaved elems of the cache. - Cache writes allways save a coherent state.  Unlike  syncChaceG this call deletes some elems of the cache when the number of elems >  sizeObjects. P The deletion depends on the check criteria, expressed by the first parameter.  Ya is the one implemented to be passed by default. Look at it to understand the clearing criteria. YRThis is a default cache clearance check. It forces to drop from the cache all the E elems not accesed since half the time between now and the last sync A if it returns True, the object will be discarded from the cache L it is invoked when the cache size exceeds the number of objects configured  in T or X Z?stablishes the procedures to call before and after saving with U, X or T. The postcondition of * database persistence should be a commit. [KAssures that the IO computation finalizes no matter if the STM transaction F is aborted or retried. The IO computation run in a different thread. X The STM transaction wait until the completion of the IO procedure (or retry as usual). >It can be retried if the embedding STM computation is retried + so the IO computation must be idempotent. 2 Exceptions are bubbled up to the STM transaction A789:;<=>?@ABCDEFGHIJKLM&the list of resources to be retrieved OThe function that process the resources found and return a Resources structure #The return value in the STM monad. NOPQRSTInumber of seconds betwen checks. objects not written to disk are written ?The user-defined check-for-cleanup-from-cache for each object. Y is an example EThe max number of objects in the cache, if more, the cleanup starts !Identifier of the thread created UVWXYcurrent time in seconds $last access time for a given object 7last cache syncronization (with the persisten storage) \return true for all the elems not accesed since half the time between now and the last sync Z[7 5789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[7W[EDFBCG MONQPSR5IJKL>?@UZXAV7=98:;<TYH77=98:;<>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[ None(*+*+(NoneDimplement the relational-like operators, operating on record fields dMRegister a trigger for indexing the values of the field passed as parameter. C the indexed field can be used to perform relational-like searches e[return all the (indexed) values which this field has and a DBRef pointer to the register (\]^_`abcdef \]^_`abcdef d_cba`ef^]\\]^_`abcdefNoneg:start a trigger to index the contents of a register field hHtrigger the indexation of list fields with elements convertible to Text itreturn the DBRefs of the registers whose field (first parameter, usually a container) contains the requested value. jDreturn all the values of a given field (if it has been indexed with d) k_return the DBRefs whose fields include all the words in the requested text contents.Except the x words with less than three characters that are not digits or uppercase, that are filtered out before making the query gfield to index >method to convert the field content to lazy Text (for example E in case of String fields). This permits to index non Textual fields hfield to index 7method to convert a field element to Text (for example ` pack . show`) in case of elemets with Show instances) ijkfield to search in text to search ghijkghkijghijkNonel;to execute a monad for the purpose of memoizing its result nEgiven a string, return a key that can be used in Indexable instances ^ Of non persistent objects, such are cached objects (it changes fron execution to execution)  . It uses  oamemoize the result of a computation for a certain time. This is useful for caching costly data & such web pages composed on the fly. time == 0 means infinite pAMemoize the result of a computation for a certain time. A string  is used to index the result The Int parameter is the timeout, in second after the last evaluation, after which the cached value will be discarded and the expression will be evaluated again if demanded  . Time == 0 means no timeout sa pure version of cached lmnopqrslmnopqrsopqrsnlmlmnopqrsNonetA queue reference u(push an element at the top of the queue vCheck if the queue is empty x;Get the reference to new or existing queue trough its name y+Empty the queue (factually, it is deleted) zVersion in the STM monad {9Read the first element in the queue and delete it (pop) |Version in the STM monad ~Push an element in the queue Version in the STM monad JReturn the list of all elements in the queue. The queue remains unchanged Version in the STM monad =Return the first element in the queue that has the given key Version in the STM monad KUpdate the first element of the queue with a new element with the same key Version in the STM monad :Return the list of all elements in the queue and empty it A version in the STM monad NDelete all the elements of the queue that has the key of the parameter passed Verison in the STM monad "t  uvwxyz{ Queue name the returned elems  |} Queue name the returned elems ~  tuvwxyz{|}~tx{|}yz~uvwt  uvwxyz{ |}~   None   !"#$%&''())*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                    TCache-0.10.2.0 Data.TCacheData.TCache.IResourceData.TCache.DefsData.TCache.TriggersData.TCache.IndexQueryData.TCache.IndexTextData.TCache.MemoizationData.Persistent.CollectionData.Persistent.IDynamicData.TCache.DefaultPersistencebase GHC.Conc.Sync atomically unsafeIOToSTMSTM ResourcestoAddtoDeletetoReturnRetry IResource keyResourcereadResourceByKey readResource writeResource delResource resourcesPersist readByKeywritedelete Serializable serialize deserialize setPersist IndexablekeydefPathDBRefTPVarElemStatusExist DoNotExistNotRead ModifTime AccessTimecastErr filePersistdefaultPersistIORefsetDefaultPersistgetDefaultPersist getPersistdefaultReadByKey defaultWrite safeWrite defaultDeletedefReadResourceByKeydefWriteResourcedefDelResourcereadFileStrict addTrigger applyTriggersSyncMode SyncManual Asyncronous frecuencycheck cacheSize SynchronousCachesetCachenewCachenumElems readDBRef writeDBRef keyObjDBRefgetDBRefnewDBRefdelDBRef onNothing flushDBRefflushKey invalidateKeyflushAllwithSTMResources withResource withResources getResource getResourcesdeleteResourcedeleteResourcesclearSyncCacheProc syncCache syncWriteatomicallySyncclearSyncCache defaultCheck setConditions safeIOToSTMselect.||..&&..==..>..>=..<=..<.indexindexOf recordsWith indexText indexList containsElem allElemsOfcontains ExecutableexecuteaddrStr writeCached cachedByKeycachedByKeySTM flushCachedcachedpRefQueue unreadSTMisEmpty isEmptySTMgetQRefflushflushSTMpoppopSTMpickpushpushSTMpickAll pickAllSTMpickElem pickElemSTM updateElem updateElemSTMreadAll readAllSTM deleteElem deleteElemSTMSaveIDynTypeDLeftDRightIDynamicIDyntosave errorfied dynPrefix dynPrefixSp notreifiedtoIDynserializedEqualfromIDyn safeFromIDynreifyMGHC.ReadReadGHC.ShowShow $fIndexable()$fIndexableInteger$fIndexableInt $fIndexable[] Data.MaybeNothing CMTrigger TriggerType cmtriggersmbToListmapM2_refcacheFilteredCheckTPVarFlags NoAddToHash AddToHashHt CacheElem deRefWeakSTM fixToCache takeDBRefs takeDBRef timeInteger releaseTPVars releaseTPVardelListFromHashupdateListToHashcriticalSection tvSyncWrite refConditionssavingsaveextract $fOrdDBRef $fEqDBRef $fReadDBRef $fShowDBRef $fIResourcea RelationOpsSelect SetOperationsJoinDataIndex QueriablekeyIndexgetIndex getIndexr selectorIndexjoinretrieve$fSelect(,)STMSTM$fSelect(,,,)STMSTM$fSelect(,,)STMSTM$fSelect(,)STMSTM0$fSelect(->)STMSTM$fSetOperations[][][]$fSetOperations[][][]0$fSetOperations[][][]1$fSetOperations[][][]2$fRelationOps(->)(->)[]$fRelationOps(->)a[]$fIResourceIndex$fIndexableIndex$fSerializableIndex $fReadIndex$fQueriablerega IndexText fieldTypelastDoc mapDocKeyInt mapIntDocKeymapTextInteger readInitDBRefadddelopbytestring-0.10.0.2Data.ByteString.Lazy.Char8packindextwords1 filterWordt filterWord$fIResourceIndexText$fIndexableIndexText$fSerializableIndexText$fReadIndexText$fShowIndexTextRefSerialize-0.3.1.0Data.RefSerialize.SerializeaddrHashCachedcontextcachedKeyPrefixcached cachedSTM$fIResourceCached$fMonadIOIdentity$fExecutableIdentity$fExecutableIOQueuenameimpout!> queuePrefix lenQPrefixreadQRef$fSerializableQueue$fSerializeQueue$fIndexableQueue$fShowIDynamic$fSerializeIDynamic$fSerializeSave