úÎ ·Y±qQ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOP  experimentalQQR>Requires NULL-terminated bytestring -> unsafe! Use with care. STUVWXYZ[R TUVWXYZ[R \,Pointer to a filesystem, possibly with start/end offsets. Supposed to be 1 fed to (uncurry mmapFileByteString) or similar. ]2Bad and ugly. Only works well with single-chunk BL's. FRead in a FileSegment into a Lazy ByteString. Implemented using mmap. ^Run an IO action with path) as a working directory. Does neccessary  bracketing. \_`]^abcde \_`]^abcdeUnsafe. Unsafe. 2Check whether a path is a prefix of another path. (Append an element to the end of a path. ACatenate two paths together. Not very safe, but sometimes useful L (e.g. when you are representing paths relative to a different point than a  Tree root). &Get parent (path) of a given path. foobar baz -> foo/bar %List all parents of a given path. foobarbaz -> [foo, foo/bar] Take a root3 directory and an anchored path and produce a full  f . Moreover, you can use  anchorPath "" to get a relative  f .     "Abstraction of a filesystem tree. K Please note that the Tree returned by the respective read operations will F have TreeStub items in it. To obtain a Tree without such stubs, call  expand on it, eg.:  * tree <- readDarcsPristine "." >>= expand $When a Tree is expanded, it becomes final. All stubs are forced and the J Tree can be traversed purely. Access to actual file contents stays in IO  though. 9A Tree may have a Hash associated with it. A pair of Tree's is identical K whenever their hashes are (the reverse need not hold, since not all Trees  come equipped with a hash). 3Get hash of a Tree. This is guaranteed to uniquely ; identify the Tree (including any blob content), as far as < cryptographic hashes are concerned. Sha256 is recommended. 4When implementing a Tree that has complex expanding  semantics, the finish$ IO action lets you do arbitrary IO = transform on the Tree after it is expanded but before it is 7 given to the user by expand. (Used to implement Index  updates, eg.) *Get a hash of a TreeItem. May be Nothing. & Look up a & item (an immediate subtree or blob). 'Find a  by its path. Gives g  if the path is invalid. (Find a  by its path. Gives g ! if the path is invalid, or does  not point to a Blob. )Find a  by its path. Gives g ! if the path is invalid, or does  not point to a Tree. *List all contents of a . +HUnfold a stubbed Tree into a one with no stubs in it. You might want to . filter the tree before expanding to save IO. ,JUnfold a path in a (stubbed) Tree, such that the leaf node of the path is ' reachable without crossing any stubs. -Given two Trees, a guide and a tree , produces a new Tree that is a  identical to tree4, but only has those items that are present in both  tree and guide. The guide! Tree may not contain any stubs. .FGiven a predicate of the form AnchoredPath -> TreeItem -> Bool, and a K Tree, produce a Tree that only has items for which the predicate returned M True. The tree might contain stubs. When expanded, these will be subject to  filtering as well. /IRead a Blob into a Lazy ByteString. Might be backed by an mmap, use with  care. 0CFor every pair of corresponding blobs from the two supplied trees, L evaluate the supplied function and accumulate the results in a list. Hint: E to get IO actions through, just use sequence on the resulting list.  NB. This won't expand any stubs. 1GFor each file in each of the two supplied trees, evaluate the supplied M function (supplying the corresponding file from the other tree, or Nothing) M and accumulate the results in a list. Hint: to get IO actions through, just 2 use sequence on the resulting list. NB. This won't expand any stubs. 3KCautiously extracts differing subtrees from a pair of Trees. It will never N do any unneccessary expanding. Tree hashes are used to cut the comparison as N high up the Tree branches as possible. The result is a pair of trees that do N not share any identical subtrees. They are derived from the first and second I parameters respectively and they are always fully expanded. It might be & advantageous to feed the result into 1. % !"#$%&'()*+,-./01234)$%"#+,*&'() !0123/.-4# !"#$%&'()*+,-./01234 hFDescription of a a single indexed item. The structure itself does not I contain any data, just pointers to the underlying mmap (bytestring is a  pointer + offset + length). KThe structure is recursive-ish (as opposed to flat-ish structure, which is % used by git...) It turns out that it'(s hard to efficiently read a flat index L with our internal data structures -- we need to turn the flat index into a M recursive Tree object, which is rather expensive... As a bonus, we can also 5 efficiently implement subtree queries this way (cf. 5). iILay out the basic index item structure in memory. The memory location is I given by a ForeignPointer () and an offset. The path and type given are L written out, and a corresponding Item is given back. The remaining bits of " the item can be filled out using j. kKRead the on-disk representation into internal data structure. The Index is  organised into lines, where each line describes a single indexed  item. Cf. lh. The first word on the index line* is the length of the file path (which is N the only variable-length part of the line). Then comes the path itself, then M fixed-length hash (sha256) of the file in question, then two words, one for  size and one aux;, which is used differently for directories and for files. LWith directories, this aux holds the offset of the next sibling line in the K index, so we can efficiently skip reading the whole subtree starting at a D given directory (by just seeking aux bytes forward). The lines are N pre-ordered with respect to directory structure -- the directory comes first & and after it come all its items. Cf. m. ,For files, the aux field holds a timestamp. jIUpdate an existing item with new hash and optionally mtime (give Nothing # when updating directory entries). nGGives a ForeignPtr to mmapped index, which can be used for reading and  updates. mSee 5<. This version also gives a map from paths to items, so the L extra per-item data can be used (hash and mtime) directly. The map is in a  form of o >, since the data is not available until the tree is expanded. 5Read an index and build up a & object from it, referring to current L working directory. Any parts of the index that are out of date are updated ? in-place. The result is always an up-to-date index. Also, the  is L stubby and only the pieces of the index that are expanded will be actually 5 updated! To implement a subtree query, you can use  Tree.filter and then M expand the result. Otherwise just expand the whole tree to avoid unexpected  problems. 68Will add and remove files in index to make it match the  object  given (it is an error for the % to contain a file or directory that ? does not exist in a plain form in current working directory). 7ERead index (just like readIndex). However, also check that the index L version matches our expectations and if not, rebuild it from the reference K (which is provided in form of un-executed action; we will only execute it  when needed). 567567567<ACompute a darcs-compatible hash value for a tree-like structure. 89:;<89:;<89:;< =A =) monad. A sort of like IO but it keeps a > around as well, K which is a sort of virtual filesystem. Depending on how you obtained your  =F, the actions in your virtual filesystem get somehow reflected in the  actual real filesystem. For A, nothing happens in real  filesystem, however with C', the plain tree will be updated every  now and then, and with B$ a darcs-style hashed tree will get  updated. >Internal state of the =( monad. Keeps track of the current Tree  content, unsync':d changes and a current working directory (of the monad). AIRun a TreeIO action without dumping anything to disk. Useful for running G tree mutations just for the purpose of getting the resulting Tree and  throwing it away. pCreate a hashed file from a f & and content. In case the file exists L it is kept untouched and is assumed to have the right content. XXX Corrupt L files should be probably renamed out of the way automatically or something - (probably when they are being read though). BRun a = action in a hashed setting. The initial tree is assumed  to be fully available from the  directory", and any changes will be written J out to same. Please note that actual filesystem files are never removed. 4XXX This somehow manages to leak memory, somewhere. CRun a =; action in a plain tree setting. Writes out changes to the L plain tree every now and then (after the action is finished, the last tree G state is always flushed to disk). XXX Modify the tree with filesystem N reading and put it back into st (ie. replace the in-memory Blobs with normal " ones, so the memory can be GCd). DCheck for existence of a file. E7Check for existence of a node (file or directory, doesn' t matter). F>Grab content of a file in the current Tree at the given path. qHInternal. Mark a given path as changed, so the next sync will flush the  modified object to disk. GHChange content of a file at a given path. The change will be eventually 7 flushed to disk, but might be buffered for some time. r;If buffers are becoming large, sync, otherwise do nothing. =>?@ABCDEFGHIJBCAFGHJIDE@?>?@==>?@?@ABCDEFGHIJKITake a relative FilePath and turn it into an AnchoredPath. The operation F is unsafe and if you break it, you keep both pieces. More useful for ; exploratory purposes (ghci) than for serious programming. LETake a relative FilePath within a Tree and print the contents of the H object there. Useful for exploration, less so for serious programming. M?Read in a plain directory hierarchy from a filesystem. NB. The / C function on Blobs with such a Tree is susceptible to file content  changes. Since we use mmap in /, this will break referential K transparency and produce unexpected results. Please always make sure that E all parallel access to the underlying filesystem tree never mutates B files. Unlink + recreate is fine though (in other words, the sync/write  operations below are safe). sCRead and parse a darcs-style hashed directory listing from a given dir  and with a given hash. NERead in a darcs-style hashed tree. This is mainly useful for reading  "pristine.hashed":. You need to provide the root hash you are interested in  (found in _darcs/hashed_inventory). OERead in a darcs pristine tree. Handles the plain and hashed pristine H cases. Does not (and will not) handle the no-pristine case, since that ! requires replaying patches. Cf. N and M that  are used to do the actual  construction. PJWrite out *full* tree to a plain directory structure. If you instead want ' to make incremental updates, refer to Monad.plainTreeIO. /KLMNOPMNO/PKLKLMNOPt    !"#$%&'())*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\ ]^_`abcNde f [ g h i j k l m n op qrsturvw oxyz{|}hashed-storage-0.3.4Storage.Hashed.TreeStorage.HashedStorage.Hashed.AnchoredPathStorage.Hashed.IndexStorage.Hashed.DarcsStorage.Hashed.MonadBundled.SHA256 Bundled.PosixStorage.Hashed.Utilsbase System.IO Data.Maybe Data.IORefHash readSegment AnchoredPathNamenameToFilePathnameFromFilePathisPrefix appendPathcatPathsparentparents anchorPathfloatBSflattenmakeNameTreeitems listImmediatetreeHashfinishItemTypeTreeTypeBlobTypeTreeItemStubSubTreeFileBlobitemHashitemType emptyTree emptyBlobmakeTreemakeTreeWithHashlookupfindfindFilefindTreelistexpand expandPathrestrictfilterreadzipCommonFileszipFileszipTrees diffTrees modifyTree readIndexupdateIndexFromreadOrUpgradeIndexdarcsFormatSizedarcsFormatHashdarcsDecodeWhitedarcsFormatDir darcsTreeHashTreeIO TreeStatecwdtree virtualTreeIO hashedTreeIO plainTreeIO fileExistsexistsreadFile writeFilecreateDirectoryunlinkrename floatPath printPath readPlainTreereadDarcsHashedreadDarcsPristinewritePlainTreesha256getFileStatusBSSystem.Posix.Types EpochTime FileStatus getFdStatus isDirectorymodificationTimefileSizegetSymbolicLinkStatus getFileStatus FileSegmentwithCurrentDirectorymakeHash hashSetSize? makeAbsolutepokeBSxlate32xlate64 GHC.IOBaseFilePathNothingItem createItemupdatepeekItem readIndex' mmapIndexIOReffsCreateHashedFile markChanged maybeSyncreadDarcsHashedDir