darcs-2.18.2: a distributed, interactive, smart revision control system

Safe Haskell | None
Language | Haskell2010

Darcs.Util.Tree

Contents

- Unfolding stubbed (lazy) Trees.
- Tree access and lookup.
- Files (Blobs).
- Filtering trees.
- Manipulating trees.
- Properties

Description

The abstract representation of a Tree and useful abstract utilities to handle those.

Synopsis

- data Tree (m :: Type -> Type)
- data Blob (m :: Type -> Type) = Blob !(m ByteString) !(Maybe Hash)
- data TreeItem (m :: Type -> Type)
  - = File !(Blob m)
  - | SubTree !(Tree m)
  - | Stub !(m (Tree m)) !(Maybe Hash)
- data ItemType
  - = TreeType
  - | BlobType
- data Hash
- makeTree :: forall (m :: Type -> Type). [(Name, TreeItem m)] -> Tree m
- makeTreeWithHash :: forall (m :: Type -> Type). [(Name, TreeItem m)] -> Hash -> Tree m
- emptyTree :: forall (m :: Type -> Type). Tree m
- emptyBlob :: forall (m :: Type -> Type). Monad m => Blob m
- makeBlob :: forall (m :: Type -> Type). Monad m => ByteString -> Blob m
- makeBlobBS :: forall (m :: Type -> Type). Monad m => ByteString -> Blob m
- expandUpdate :: Monad m => (AnchoredPath -> Tree m -> m (Tree m)) -> Tree m -> m (Tree m)
- expand :: Monad m => Tree m -> m (Tree m)
- expandPath :: Monad m => Tree m -> AnchoredPath -> m (Tree m)
- checkExpand :: (TreeItem IO -> IO Hash) -> Tree IO -> IO (Either [(AnchoredPath, Maybe Hash, Maybe Hash)] (Tree IO))
- items :: Tree m -> Map Name (TreeItem m)
- list :: forall (m :: Type -> Type). Tree m -> [(AnchoredPath, TreeItem m)]
- listImmediate :: forall (m :: Type -> Type). Tree m -> [(Name, TreeItem m)]
- treeHash :: Tree m -> Maybe Hash
- lookup :: forall (m :: Type -> Type). Tree m -> Name -> Maybe (TreeItem m)
- find :: forall (m :: Type -> Type). Tree m -> AnchoredPath -> Maybe (TreeItem m)
- findFile :: forall (m :: Type -> Type). Tree m -> AnchoredPath -> Maybe (Blob m)
- findTree :: forall (m :: Type -> Type). Tree m -> AnchoredPath -> Maybe (Tree m)
- itemHash :: forall (m :: Type -> Type). TreeItem m -> Maybe Hash
- itemType :: forall (m :: Type -> Type). TreeItem m -> ItemType
- zipCommonFiles :: forall (m :: Type -> Type) a. (AnchoredPath -> Blob m -> Blob m -> a) -> Tree m -> Tree m -> [a]
- zipFiles :: forall (m :: Type -> Type) a. (AnchoredPath -> Maybe (Blob m) -> Maybe (Blob m) -> a) -> Tree m -> Tree m -> [a]
- zipTrees :: forall (m :: Type -> Type) a. (AnchoredPath -> Maybe (TreeItem m) -> Maybe (TreeItem m) -> a) -> Tree m -> Tree m -> [a]
- diffTrees :: Monad m => Tree m -> Tree m -> m (Tree m, Tree m)
- explodePath :: forall (m :: Type -> Type). Tree m -> AnchoredPath -> [AnchoredPath]
- explodePaths :: Tree IO -> [AnchoredPath] -> [AnchoredPath]
- locate :: Monad m => Tree m -> AnchoredPath -> m (Maybe (TreeItem m))
- isDir :: forall (m :: Type -> Type). TreeItem m -> Bool
- treeHas :: Monad m => Tree m -> AnchoredPath -> m Bool
- treeHasDir :: Monad m => Tree m -> AnchoredPath -> m Bool
- treeHasFile :: Monad m => Tree m -> AnchoredPath -> m Bool
- treeHasAnycase :: Monad m => Tree m -> AnchoredPath -> m Bool
- readBlob :: Blob m -> m ByteString
- class Monad m => FilterTree (a :: (Type -> Type) -> Type) (m :: Type -> Type) where
  - filter :: (AnchoredPath -> TreeItem m -> Bool) -> a m -> a m
- restrict :: forall t (m :: Type -> Type) (n :: Type -> Type). FilterTree t m => Tree n -> t m -> t m
- modifyTree :: forall (m :: Type -> Type). Monad m => Tree m -> AnchoredPath -> Maybe (TreeItem m) -> Tree m
- updateTree :: Monad m => (TreeItem m -> m (TreeItem m)) -> Tree m -> m (Tree m)
- partiallyUpdateTree :: Monad m => (TreeItem m -> m (TreeItem m)) -> (AnchoredPath -> TreeItem m -> Bool) -> Tree m -> m (Tree m)
- updateSubtrees :: forall (m :: Type -> Type). (Tree m -> Tree m) -> Tree m -> Tree m
- overlay :: forall (m :: Type -> Type). Applicative m => Tree m -> Tree m -> Tree m
- addMissingHashes :: Monad m => (TreeItem m -> m Hash) -> Tree m -> m (Tree m)
- prop_explodePath :: forall (m :: Type -> Type). Tree m -> AnchoredPath -> Bool

# Documentation

data Tree (m :: Type -> Type) #

Abstraction of a filesystem tree. Please note that the Tree returned by the respective read operations will 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 Tree can be traversed purely. Access to actual file contents stays in IO though.

A Tree may have a Hash associated with it. A pair of Tree's is identical whenever their hashes are (the reverse need not hold, since not all Trees come equipped with a hash).

#### Instances

Instances details

ApplyMonad Tree DefaultIO # |
Instance details Defined in Darcs.Repository.ApplyPatches Methods readFilePS :: ObjectIdOf Tree -> DefaultIO ByteString #
MonadThrow m => ApplyMonadTrans Tree m # |

Instance details

Defined in Darcs.Patch.ApplyMonad

Associated Types

type ApplyMonadOver Tree m |
Instance details Defined in Darcs.Patch.ApplyMonad type ApplyMonadOver Tree m = TreeMonad m

Methods

runApplyMonad :: ApplyMonadOver Tree m x -> Tree m -> m (x, Tree m) #

Monad m => FilterTree Tree m # |
Instance details Defined in Darcs.Util.Tree Methods filter :: (AnchoredPath -> TreeItem m -> Bool) -> Tree m -> Tree m #
MonadThrow m => ApplyMonad Tree (TreeMonad m) # |
Instance details Defined in Darcs.Patch.ApplyMonad Methods readFilePS :: ObjectIdOf Tree -> TreeMonad m ByteString #
type ApplyMonadOperations Tree # |
Instance details Defined in Darcs.Patch.ApplyMonad type ApplyMonadOperations Tree = ApplyMonadTree
type ObjectIdOf Tree # |
Instance details Defined in Darcs.Patch.Object type ObjectIdOf Tree = AnchoredPath
type ApplyMonadOver Tree m # |
Instance details Defined in Darcs.Patch.ApplyMonad type ApplyMonadOver Tree m = TreeMonad m

data Blob (m :: Type -> Type) #

Constructors

Blob !(m ByteString) !(Maybe Hash) |

data TreeItem (m :: Type -> Type) #

Constructors

File !(Blob m) |
SubTree !(Tree m) |
Stub !(m (Tree m)) !(Maybe Hash) |

#### Instances

Instances details

MonadThrow m => ApplyMonad Tree (TreeMonad m) # |
Instance details Defined in Darcs.Patch.ApplyMonad Methods readFilePS :: ObjectIdOf Tree -> TreeMonad m ByteString #
MonadThrow m => ApplyMonadTree (TreeMonad m) # |

Instance details

Defined in Darcs.Patch.ApplyMonad

Methods

mDoesDirectoryExist :: AnchoredPath -> TreeMonad m Bool #

mDoesFileExist :: AnchoredPath -> TreeMonad m Bool #

mReadFilePS :: AnchoredPath -> TreeMonad m ByteString #

mCreateDirectory :: AnchoredPath -> TreeMonad m () #

mRemoveDirectory :: AnchoredPath -> TreeMonad m () #

mCreateFile :: AnchoredPath -> TreeMonad m () #

mRemoveFile :: AnchoredPath -> TreeMonad m () #

mRename :: AnchoredPath -> AnchoredPath -> TreeMonad m () #

mModifyFilePS :: AnchoredPath -> (ByteString -> TreeMonad m ByteString) -> TreeMonad m () #

mChangePref :: String -> String -> String -> TreeMonad m () #

data ItemType #

Constructors

TreeType |
BlobType |

#### Instances

Instances details

Show ItemType # |
Instance details Defined in Darcs.Util.Tree Methods showsPrec :: Int -> ItemType -> ShowS # show :: ItemType -> String # showList :: [ItemType] -> ShowS #
Eq ItemType # |
Instance details Defined in Darcs.Util.Tree Methods (==) :: ItemType -> ItemType -> Bool # (/=) :: ItemType -> ItemType -> Bool #
Ord ItemType # |
Instance details Defined in Darcs.Util.Tree Methods compare :: ItemType -> ItemType -> Ordering # (<) :: ItemType -> ItemType -> Bool # (<=) :: ItemType -> ItemType -> Bool # (>) :: ItemType -> ItemType -> Bool # (>=) :: ItemType -> ItemType -> Bool # max :: ItemType -> ItemType -> ItemType # min :: ItemType -> ItemType -> ItemType #

data Hash #

#### Instances

Instances details

Read Hash # |
Instance details Defined in Darcs.Util.Hash Methods readsPrec :: Int -> ReadS Hash # readList :: ReadS [Hash] # readPrec :: ReadPrec Hash # readListPrec :: ReadPrec [Hash] #
Show Hash # |
Instance details Defined in Darcs.Util.Hash Methods showsPrec :: Int -> Hash -> ShowS # show :: Hash -> String # showList :: [Hash] -> ShowS #
Eq Hash # |
Instance details Defined in Darcs.Util.Hash Methods (==) :: Hash -> Hash -> Bool # (/=) :: Hash -> Hash -> Bool #
Ord Hash # |
Instance details Defined in Darcs.Util.Hash Methods compare :: Hash -> Hash -> Ordering # (<) :: Hash -> Hash -> Bool # (<=) :: Hash -> Hash -> Bool # (>) :: Hash -> Hash -> Bool # (>=) :: Hash -> Hash -> Bool # max :: Hash -> Hash -> Hash # min :: Hash -> Hash -> Hash #

makeTree :: forall (m :: Type -> Type). [(Name, TreeItem m)] -> Tree m #

makeTreeWithHash :: forall (m :: Type -> Type). [(Name, TreeItem m)] -> Hash -> Tree m #

emptyTree :: forall (m :: Type -> Type). Tree m #

emptyBlob :: forall (m :: Type -> Type). Monad m => Blob m #

makeBlob :: forall (m :: Type -> Type). Monad m => ByteString -> Blob m #

makeBlobBS :: forall (m :: Type -> Type). Monad m => ByteString -> Blob m #

# Unfolding stubbed (lazy) Trees.

By default, Tree obtained by a read function is stubbed: it will contain Stub items that need to be executed in order to access the respective subtrees. `expand` will produce an unstubbed Tree.

expandUpdate :: Monad m => (AnchoredPath -> Tree m -> m (Tree m)) -> Tree m -> m (Tree m) #

expand :: Monad m => Tree m -> m (Tree m) #

Expand 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 implementation, which may be overriden by some Tree instances (this is especially true of the Index case).

expandPath :: Monad m => Tree m -> AnchoredPath -> m (Tree m) #

Unfold a path in a (stubbed) Tree, such that the leaf node of the path is reachable without crossing any stubs. Moreover, the leaf ought not be a Stub in the resulting Tree. A non-existent path is expanded as far as it can be.

checkExpand :: (TreeItem IO -> IO Hash) -> Tree IO -> IO (Either [(AnchoredPath, Maybe Hash, Maybe Hash)] (Tree IO)) #

Check the disk version of a Tree: expands it, and checks each hash. Returns either the expanded tree or a list of AnchoredPaths where there are problems. The first argument is the hashing function used to create the tree.

# Tree access and lookup.

items :: Tree m -> Map Name (TreeItem m) #

list :: forall (m :: Type -> Type). Tree m -> [(AnchoredPath, TreeItem m)] #

List all contents of a `Tree`.

listImmediate :: forall (m :: Type -> Type). Tree m -> [(Name, TreeItem m)] #

treeHash :: Tree m -> Maybe Hash #

Get 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.

lookup :: forall (m :: Type -> Type). Tree m -> Name -> Maybe (TreeItem m) #

Look up a `Tree` item (an immediate subtree or blob).

find :: forall (m :: Type -> Type). Tree m -> AnchoredPath -> Maybe (TreeItem m) #

Find a `TreeItem` by its path. Gives `Nothing` if the path is invalid.

findFile :: forall (m :: Type -> Type). Tree m -> AnchoredPath -> Maybe (Blob m) #

Find a `Blob` by its path. Gives `Nothing` if the path is invalid, or does not point to a Blob.

findTree :: forall (m :: Type -> Type). Tree m -> AnchoredPath -> Maybe (Tree m) #

Find a `Tree` by its path. Gives `Nothing` if the path is invalid, or does not point to a Tree.

itemHash :: forall (m :: Type -> Type). TreeItem m -> Maybe Hash #

Get a hash of a TreeItem. May be Nothing.

itemType :: forall (m :: Type -> Type). TreeItem m -> ItemType #

zipCommonFiles :: forall (m :: Type -> Type) a. (AnchoredPath -> Blob m -> Blob m -> a) -> Tree m -> Tree m -> [a] #

For every pair of corresponding blobs from the two supplied trees, evaluate the supplied function and accumulate the results in a list. Hint: to get IO actions through, just use sequence on the resulting list. NB. This won't expand any stubs.

zipFiles :: forall (m :: Type -> Type) a. (AnchoredPath -> Maybe (Blob m) -> Maybe (Blob m) -> a) -> Tree m -> Tree m -> [a] #

For each file in each of the two supplied trees, evaluate the supplied function (supplying the corresponding file from the other tree, or Nothing) and accumulate the results in a list. Hint: to get IO actions through, just use sequence on the resulting list. NB. This won't expand any stubs.

zipTrees :: forall (m :: Type -> Type) a. (AnchoredPath -> Maybe (TreeItem m) -> Maybe (TreeItem m) -> a) -> Tree m -> Tree m -> [a] #

diffTrees :: Monad m => Tree m -> Tree m -> m (Tree m, Tree m) #

Cautiously extracts differing subtrees from a pair of Trees. It will never do any unneccessary expanding. Tree hashes are used to cut the comparison as high up the Tree branches as possible. The result is a pair of trees that do not share any identical subtrees. They are derived from the first and second parameters respectively and they are always fully expanded. It might be advantageous to feed the result into `zipFiles` or `zipTrees`.

explodePath :: forall (m :: Type -> Type). Tree m -> AnchoredPath -> [AnchoredPath] #

All paths in the tree that that have the given path as prefix.

    explodePath t p == Prelude.filter (p `isPrefix`) (map fst (list t))

explodePaths :: Tree IO -> [AnchoredPath] -> [AnchoredPath] #

Like `explodePath` but for multiple paths.

locate :: Monad m => Tree m -> AnchoredPath -> m (Maybe (TreeItem m)) #

Like `find` but monadic and thus able to expand `Stub`s on the way.

isDir :: forall (m :: Type -> Type). TreeItem m -> Bool #

treeHas :: Monad m => Tree m -> AnchoredPath -> m Bool #

treeHasDir :: Monad m => Tree m -> AnchoredPath -> m Bool #

treeHasFile :: Monad m => Tree m -> AnchoredPath -> m Bool #

treeHasAnycase :: Monad m => Tree m -> AnchoredPath -> m Bool #

# Files (Blobs).

readBlob :: Blob m -> m ByteString #

Read a Blob into a Lazy ByteString. Might be backed by an mmap, use with care.

# Filtering trees.

class Monad m => FilterTree (a :: (Type -> Type) -> Type) (m :: Type -> Type) where #

Methods

filter :: (AnchoredPath -> TreeItem m -> Bool) -> a m -> a m #

Given `pred tree`, produce a `Tree` that only has items for which `pred` returns `True`. The tree might contain stubs. When expanded, these will be subject to filtering as well.

#### Instances

Instances details

Monad m => FilterTree Tree m # |
Instance details Defined in Darcs.Util.Tree Methods filter :: (AnchoredPath -> TreeItem m -> Bool) -> Tree m -> Tree m #

restrict :: forall t (m :: Type -> Type) (n :: Type -> Type). FilterTree t m => Tree n -> t m -> t m #

Given two Trees, a `guide` and a `tree`, produces a new Tree that is a identical to `tree`, but only has those items that are present in both `tree` and `guide`. The `guide` Tree may not contain any stubs.

# Manipulating trees.

modifyTree :: forall (m :: Type -> Type). Monad m => Tree m -> AnchoredPath -> Maybe (TreeItem m) -> Tree m #

Modify a Tree (by replacing, or removing or adding items).

updateTree :: Monad m => (TreeItem m -> m (TreeItem m)) -> Tree m -> m (Tree m) #

Does not expand the tree.

partiallyUpdateTree :: Monad m => (TreeItem m -> m (TreeItem m)) -> (AnchoredPath -> TreeItem m -> Bool) -> Tree m -> m (Tree m) #

Does not expand the tree.

updateSubtrees :: forall (m :: Type -> Type). (Tree m -> Tree m) -> Tree m -> Tree m #

overlay :: forall (m :: Type -> Type). Applicative m => Tree m -> Tree m -> Tree m #

Lay one tree over another. The resulting Tree will look like the base (1st parameter) Tree, although any items also present in the overlay Tree will be taken from the overlay. It is not allowed to overlay a different kind of an object, nor it is allowed for the overlay to add new objects to base. This means that the overlay Tree should be a subset of the base Tree (although any extraneous items will be ignored by the implementation).

addMissingHashes :: Monad m => (TreeItem m -> m Hash) -> Tree m -> m (Tree m) #

Calculate and insert hashes for all `TreeItem`s contained in a `Tree`, including the argument `Tree` itself. If necessary, this expands `Stub`s.

# Properties

prop_explodePath :: forall (m :: Type -> Type). Tree m -> AnchoredPath -> Bool #

Specification of `explodePath`