N      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ EProduce a base16 (ascii-hex) encoded string from a hash. This can be  turned back into a Hash (see  decodeBase16. This is a loss-less process.  Take a base64/&url-encoded string and decode it as a Hash. If the string  is malformed, yields NoHash. 0Take a base16-encoded string and decode it as a Hash. If the string is  malformed, yields NoHash. FCompute a sha256 of a (lazy) ByteString. However, although this works K correctly for any bytestring, it is only efficient if the bytestring only  has a sigle chunk.    >Requires NULL-terminated bytestring -> unsafe! Use with care.  ,Pointer to a filesystem, possibly with start/end offsets. Supposed to be 1 fed to (uncurry mmapFileByteString) or similar. FRead in a FileSegment into a Lazy ByteString. Implemented using mmap. Run an IO action with path) as a working directory. Does neccessary  bracketing. Find a monadic fixed point of f that is the least above i. (Will $ happily diverge if there is none.) Find a fixed point of f that is the least above i. (Will happily  diverge if there is none.) For a refs function, a map (key -> value) and a rootSet , find a  submap of map such that all items in map are reachable, through refs  from rootSet.   This is a type of sane3 file paths. These are always canonic in the sense % that there are no stray slashes, no .." components and similar. They are N usually used to refer to a location within a Tree, but a relative filesystem L path works just as well. These are either constructed from individual name  components (using  appendPath, catPaths and makeName), or converted  from a FilePath ( floatPath( -- but take care when doing that) or . 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  . Moreover, you can use  anchorPath "" to get a relative  . AUnsafe. Only ever use on bytestrings that came from flatten on a  pre-existing AnchoredPath. ITake a relative FilePath and turn it into an AnchoredPath. The operation K is (relatively) unsafe. Basically, by using floatPath, you are testifying N that the argument is a path relative to some common root -- i.e. the root of  the associated Tree2 object. Also, there are certain invariants about M AnchoredPath that this function tries hard to preserve, but probably cannot G guarantee (i.e. this is a best-effort thing). You should sanitize any # FilePaths before you declare them good! by converting into AnchoredPath  (using this function).      ,Given  pred tree , produce a  that only has items for which  pred returns True. G The tree might contain stubs. When expanded, these will be subject to  filtering as well. "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. !"#$%&'()*Get a hash of a TreeItem. May be Nothing. *+,-./01 Look up a & item (an immediate subtree or blob). 2Find a # by its path. Gives  if the path is invalid. 3Find a (' by its path. Gives ! if the path is invalid, or does  not point to a Blob. 4Find a  by its path. Gives ! if the path is invalid, or does  not point to a Tree. 5List all contents of a . 67HExpand a stubbed Tree into a one with no stubs in it. You might want to @ filter the tree before expanding to save IO. This is the basic H implementation, which may be overriden by some Tree instances (this is % especially true of the Index case). 8JUnfold a path in a (stubbed) Tree, such that the leaf node of the path is ' reachable without crossing any stubs. 9Given 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. :IRead a Blob into a Lazy ByteString. Might be backed by an mmap, use with  care. ;CFor 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. <GFor 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. =@Helper function for taking the union of AnchoredPath lists that D are already sorted. This function does not check the precondition  so use it carefully. >KCautiously 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 < or =. ?@ADoes not expand the tree. BKLay one tree over another. The resulting Tree will look like the base (1st N parameter) Tree, although any items also present in the overlay Tree will be M taken from the overlay. It is not allowed to overlay a different kind of an M object, nor it is allowed for the overlay to add new objects to base. This K means that the overlay Tree should be a subset of the base Tree (although > any extraneous items will be ignored by the implementation). - !"#$%&'()*+,-./0123456789:;<=>?@AB0'(#&%$ "!/0+,-.67851234)*;<=>:9?A@B) "!!"#&%$$%&'(()*+,-./0123456789:;<=>?@AB:CFDescription 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. E). ILay 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 update. KRead the on-disk representation into internal data structure. The Index is  organised into lines, where each line describes a single indexed  item. Cf. . 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.  readIndex'. ,For files, the aux field holds a timestamp. IUpdate an existing item with new hash and optionally mtime (give Nothing # when updating directory entries). GGives a ForeignPtr to mmapped index, which can be used for reading and  updates. DERead an index and build up a & object from it, referring to current J working directory. The initial Index object returned by readIndex is not ' directly useful. However, you can use  Tree.filter on it. Either way, to - obtain the actual Tree object, call update. The usual use pattern is this:   do (idx, update) <- readIndex , tree <- update =<< filter predicate idx +The resulting tree will be fully expanded. F8Will 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). GJCheck that a given file is an index file with a format we can handle. You B should remove and re-create the index whenever this is not true. CDEFGEFGDCCDEFGH=Change content of a file at a given path. The change will be B eventually flushed to disk, but might be buffered for some time. IJKLM>Grab content of a file in the current Tree at the given path. N7Check for existence of a node (file or directory, doesn' t matter). O$Check for existence of a directory. PCheck for existence of a file. QRA Q) monad. A sort of like IO but it keeps a S around as well, K which is a sort of virtual filesystem. Depending on how you obtained your  QF, the actions in your virtual filesystem get somehow reflected in the  actual real filesystem. For Y, nothing happens in real  filesystem, however with  plainTreeIO', the plain tree will be updated every  now and then, and with  hashedTreeIO$ a darcs-style hashed tree will get  updated. SInternal state of the Q( monad. Keeps track of the current Tree  content, unsync':d changes and a current working directory (of the monad). TUVWXDRun a TreeIO action without storing any changes. This is useful for M running monadic tree mutations for obtaining the resulting Tree (as opposed N to their effect of writing a modified tree to disk). The actions can do both N read and write -- reads are passed through to the actual filesystem, but the 7 writes are held in memory in a form of modified Tree. YZHInternal. Mark a given path as changed, so the next sync will flush the  modified object to disk. ;If buffers are becoming large, sync, otherwise do nothing. HIJKLMNOPQRSTUVWXYZYXMHIKJPONLTSTRQWUVZHIJKLMNOPQRSTTUVWXYZ[\ Write out full: tree to a plain directory structure. If you instead want ' to make incremental updates, refer to Storage.Hashed.Monad. ]Run a Q; 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). [\][\][\]^"Object storage. Contains a single "hatchery" and possibly a number of M mature space blocks, usually in form of packs. It also keeps a list of root E pointers and has a way to extract pointers from objects (externally E supplied). These last two things are used to implement a simple GC. _`abcdKObject storage block. When used as a hatchery, the loose or compact format I are preferable, while for mature space, the pack format is more useful. efgJOn-disk format for object storage: we implement a completely loose format M (one file per object), a compact format stored in a single append-only file  and an immutable "pack" format. hijkFReduce number of packs in the object storage. This may both recombine K packs to eliminate dead objects and join some packs to form bigger packs. lKAdd new objects to the object storage (i.e. put them into hatchery). It is L safe to call this even on objects that are already present in the storage:  such objects will be skipped. m-Move things from hatchery into a (new) pack. noFCreate an empty object storage in given directory, with a hatchery of H given format. The directory is created if needed, but is assumed to be  empty. pqKBuild a map of live objects (i.e. those reachable from the given roots) in  a given list of Blocks. ^_`abcdefghijklmnopqgjihdef^_`abclmknopfeq_`abc^_`abc_`abcdefefgjihhijklmnopqrr interprets the Darcs-specific "encoded" filenames  produced by s 4 darcsDecodeWhite "hello\32\there" == "hello there" 4 darcsDecodeWhite "hello\92\there" == "hello\there" A darcsDecodeWhite "hello\there" == error "malformed filename" ss8 translates whitespace in filenames to a darcs-specific G format (backslash followed by numerical representation according to ). O Note that backslashes are also escaped since they are used in the encoding. 4 darcsEncodeWhite "hello there" == "hello\32\there" 4 darcsEncodeWhite "hello\there" == "hello\92\there" tuvwxyzACompute a darcs-compatible hash value for a tree-like structure. {|}~CRead and parse a darcs-style hashed directory listing from a given dir  and with a given hash. ERead 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). 2Write a Tree into a darcs-style hashed directory. Create a hashed file from a & 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). Run a Q 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. MXXX This somehow manages to leak memory, in some usege scenarios (apparently 4 not even all). The only reproducer known so far is " gorsvet pull". action initial  directory GRead a Tree in the darcs hashed format from an object storage. This is H basically the same as readDarcsHashed from Storage.Hashed, but uses an M object storage instead of traditional darcs filesystem layout. Requires the % tree root hash as a starting point. EWrite a Tree into an object storage, using the darcs-style directory N formatting (and therefore darcs-style hashes). Gives back the object storage N and the root hash of the stored Tree. NB. The function expects that the Tree 1 comes equipped with darcs-style hashes already! rstuvwxyz{|}~rstuvwxyz{|}~rstuvwxyz{|}~ ETake a relative FilePath within a Tree and print the contents of the H object there. Useful for exploration, less so for serious programming. :[\[:\  !"#$%&'()*+,-./01223456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvw;xyz{|}~    Z   'MW]hnhashed-storage-0.4.6Storage.Hashed.HashStorage.Hashed.AnchoredPathStorage.Hashed.TreeStorage.Hashed.IndexStorage.Hashed.MonadStorage.Hashed.PlainStorage.Hashed.PackedStorage.Hashed.DarcsStorage.HashedBundled.SHA256 Bundled.PosixStorage.Hashed.UtilsHashNoHashSHA1SHA256 encodeBase64u encodeBase16 decodeBase64u decodeBase16sha256rawHashmatch AnchoredPathNameisPrefix appendPathcatPathsparentparents anchorPathfloatBSflattenmakeName floatPath anchoredRoot FilterTreefilterTreeitems listImmediatetreeHashItemTypeTreeTypeBlobTypeTreeItemStubSubTreeFileBlobitemHashitemType emptyTree emptyBlobmakeBlob makeBlobBSmakeTreemakeTreeWithHashlookupfindfindFilefindTreelist expandUpdateexpand expandPathrestrictreadBlobzipCommonFileszipFileszipTrees diffTrees modifyTreeupdateSubtrees updateTreeoverlayIndex updateIndex readIndexupdateIndexFromindexFormatValid writeFilecreateDirectoryunlinkrename withDirectoryreadFileexistsdirectoryExists fileExistsTreeIO TreeMonad TreeStatetreePathSet initialState runTreeMonadvirtualTreeMonad virtualTreeIO replaceItem readPlainTreewritePlainTree plainTreeIOOShatcherymatureroots referencesrootdirBlock blockLookupformatFormatPackCompactLooserepackhatchcompactcreateloadlivedarcsDecodeWhitedarcsEncodeWhitedarcsEncodeWhiteBSdecodeDarcsHashdecodeDarcsSize darcsLocationdarcsFormatDir darcsParseDir darcsTreeHashdarcsUpdateDirHashesdarcsUpdateHashesdarcsAddMissingHashesreadDarcsHashedDirreadDarcsHashedwriteDarcsHashedfsCreateHashedFile hashedTreeIOreadPackedDarcsPristinewritePackedDarcsPristinestorePackedDarcsPristinedarcsPristineRefs printPathc_sha256base16base64u debase64udebase16 FileStatus fst_existsfst_mode fst_mtimefst_size getFdStatusdo_stat isDirectorymodificationTimefileSizegetSymbolicLinkStatus getFileStatusgetFileStatusBSbaseSystem.Posix.Types EpochTime FileSegment readSegmentwithCurrentDirectory? makeAbsolute unsafePokeBSalignxlate32xlate64mfixFromfixFrom reachableGHC.IOFilePathfind' Data.MaybeNothing sortedUnionResultchangednexttreeitemresitemState dirlengthpathstartIndexM EmptyIndexmmaphashtree predicateItemiBaseiHashAndDescriptor size_magic size_sizesize_aux size_dsclen size_hashoff_sizeoff_aux off_dsclenoff_hashoff_dsc itemAllocSizeitemSizeitemNext iDescriptoriPathiHashiSizeiAux itemIsDir xlatePeek64 xlatePoke64 createItempeekItem updateItem updateAux updateTimeiHash' mmapIndexreadItemreadDir formatIndexTreeRWTreeROcurrentDirectoryexpandTo changesizesyncflush markChanged maybeFlush readPlainDirsize loose_dirs loosePath looseLookup blocksLookupreadPack createPackGHC.Baseord