úÎTyPÖ+      !"#$%&'()*non-portable (requires STM) experimental$Peter Robinson <thaldyron@gmail.com> An instance of 7 is a (Adv)STM variable that might contain a value of  some type a. In contrast to a plain 'TVar (Maybe a)', a  C has IO hooks that are executed transparently on writes and reads, ] which makes it particularly suitable for implementing a persistent and thread-safe storage.  The type variable k> can be used to provide additional storage information, e.g.,  a filepath.  Important: Note that the read/*write functions of this type class, i.e.,  , , , ,  ,   should  only be used to derive new 5 instances and do not serve to modify the state of a . ! The interface defined in module TBox.Operations provides  operations on s that guarantee consistency. See the module Control.Concurrent.TFile for a sample instance. !Takes a key and an initial value @Takes a key and an initial value. Has a default implementation. !Takes a key and returns an empty t !Takes a key and returns an empty t . Has a default implementation. Used in  TBox.write. Used in  TBox.write during the commit phase. + Is guaranteed to be executed exactly once iff the transaction commits. Used in  TBox.read Used in  TBox.read8 when retrying the transaction, which happens when the   has been marked "dirty". 0 Note: Might be executed multiple times for the  same  in a single transaction. See +. Used in  TBox.clear Used in  TBox.clear during the commit phase. + Is guaranteed to be executed exactly once iff the transaction commits. If   yields ,, the  hook will be  run on the next read.  Change the "dirty" status of the .     non-portable (requires STM) experimental$Peter Robinson <thaldyron@gmail.com> Deletes the content. Writes the new content. 7If the TBox is dirty, this retries the transaction and  rereads the content using  in a separate thread. + Otherwise it simply returns the result of . :Note: Depending on the instance implementation, careless  use of   and $ in the same transaction might lead  to nonterminating retry loops. Returns , iff the  is empty. Returns , iff the  is empty and not dirty.    non-portable (requires STM) experimental$Peter Robinson <thaldyron@gmail.com>   non-portable (requires STM) experimental*Peter Robinson <robinson@ecs.tuwien.ac.at> -./01234567An empty skiplist. %Probability for choosing a new level Maximum number of levels 8An empty skiplist. %Probability for choosing a new level Maximum number of levels 9EReturns a randomly chosen level. Is used for inserting new elements.  Note that this function uses : to access the random  number generator. 5Returns all elements that are smaller than the key. 4Returns all elements that are greater than the key. ; TODO: currently in O(n), can be made more efficient (like ) 6Returns the element with the least key, if it exists. O(1).  Reads the  of the node. If the  is empty, the node  is removed from the skip list.  This is necessary when $s are shared between different data  structures. Updates an element. Throws ;< if the element is not in the  list.  !="7Returns all elements that satisfy the predicate. O(n). #1Debug helper. Returns the skip list as a string. D All elements smaller than the given key are written to the string.  !"# "!# !"#non-portable (requires STM) experimental$Peter Robinson <thaldyron@gmail.com> $KA transactional variable that writes its content to a file on each update. " The file is created in directory "./_TFile/".  The > hook of the ?2 monad guarantee that the updated memory content / of the TFile is only visible to other threads iff the file has been written  successfully.  If the $ is "dirty"4, the content is (re)read from the file on the next  . @ABCD%Currently set to "./_TFile" M TODO: provide interface for updating base directory within a transaction(?) &Tries to construct a $ from a given filepath. , Reads the content of the file into memory. 'Tries to construct a $ from a given filepath. M Note that the content of the file is read into memory only on demand, i.e.,  when executing  TBox.read.  Throws ;<& if the filename could not be parsed. E  $%&' $&' %$%&'non-portable (requires STM) experimental*Peter Robinson <robinson@ecs.tuwien.ac.at>()Returns a new (reconstructed!) (. Automatically inserts all $ entries found  in "basedir /".  Note that the $;s are initially empty, i.e., the file content will only be  read into memory on demand. *Returns a new (reconstructed!) (. Automatically inserts all $ entries found  in "basedir /".  In contrast to ), the $&s initially contain the file content. A Use this if you want to have all data in memory from the start. F  "#()* ()* "#()*G       !"#$%&'()*+,-  ./01234456789:;<=.>?@AB@ABC./D.EFGHIJKLMN tbox-0.1.0&Control.Concurrent.TBox.Internal.Class+Control.Concurrent.TBox.Internal.Operations!Control.Concurrent.TBox.TSkipListControl.Concurrent.TFile"Control.Concurrent.TFile.TSkipListControl.Concurrent.TBoxTBoxnewnewIOnewEmpty newEmptyIOwriteSTMwriteIOreadSTMreadIOclearSTMclearIOisDirtysetDirtyclearwritereadisEmptyisEmptyNotDirtykey contentTBox TSkipListnewNode chooseLevelleqgeqminreadAndValidate lookupNodelookupupdatedeleteinsert insertNodefiltertoStringTFilebasedir newFromFileIOnewEmptyFromFileIOstm-io-hooks-0.6.0Control.Monad.AdvSTM.ClassunsafeRetryWithghc-primGHC.BoolTrueNode forwardPtrsNilmaxLevel probabilitycurLevellistHead ForwardPtrsisNilnewForwardPtrsControl.Concurrent.AdvSTMunsafeIOToAdvSTMbaseGHC.IO.ExceptionAssertionFailedtraverseonCommitControl.Monad.AdvSTM.DefAdvSTMTFfilepath tfileTVar dirtyTVarfileLock withTMVargetFilesInDirectory