[darcs-users] [patch16] Bump the hashed-storage dependency to >=... (and 1 more)
Petr Rockai
me at mornfall.net
Wed Nov 4 10:43:01 UTC 2009
Reinier Lamers <tux_rocker at reinier.de> writes:
>>unrecordedChanges :: (RepoPatch p) => [DarcsFlag] -> Repository p C(r u t)
>> -> [SubPath] -> IO (FL Prim C(r y))
>>unrecordedChanges opts repo paths = do
>> (all_current, _) <- readPending repo
>> Sealed pending <- pendingChanges repo paths
>>
>> relevant <- restrictSubpaths repo paths
>> nonboring <- restrictBoring
>>
>> let current = relevant all_current
>> working <- case (LookForAdds `elem` opts, IgnoreTimes `elem` opts) of
>> (False, False) -> do
>> I.updateIndex =<< (relevant <$> readIndex repo)
>> (False, True) -> do
>> guide <- expand current
>> all_working <- readPlainTree "."
>> return $ relevant $ (restrict guide) all_working
>>- -- TODO (True, False) could use a more efficient implementation...
>>- (True, _) -> do
>>+ (True, False) -> do
>>+ plain <- relevant <$> nonboring <$> readPlainTree "."
>>+ index <- I.updateIndex =<< (relevant <$> readIndex repo)
>>+ return $ plain `overlay` index
>>+ (True, True) -> do
>> all_working <- readPlainTree "."
>> return $ relevant $ nonboring all_working
>
> I see why this is correct, but not why it is faster. Is it that readIndex uses
> data from the index when the timestamp on the working directory file is no
> newer than the timestamp of that file in the index? But how would that help?
> Is reading a file from the index faster than reading it from disk?
The trick is that with the index, we don't read the files at all. The index has
a cached hash of the working files, which -- if timestamps match -- is used to
check against pristine hash. If they are equal, neither the working nor the
pristine files are opened at all.
>> +-- | 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).
>> +overlay :: (Functor m, Monad m) => Tree m -> Tree m -> Tree m
>> +overlay base over = Tree { items = M.fromList immediate
>> + , listImmediate = immediate
>> + , treeHash = NoHash }
>> + where immediate = [ (n, get n) | (n, _) <- listImmediate base ]
>> + get n = case (M.lookup n $ items base, M.lookup n $ items over) of
>> + (Just (File _), Just f@(File _)) -> f
>> + (Just (SubTree b), Just (SubTree o)) -> SubTree $ overlay b o
>> + (Just (Stub b _), Just (SubTree o)) -> Stub (flip overlay o `fmap` b) NoHash
>> + (Just (SubTree b), Just (Stub o _)) -> Stub (overlay b `fmap` o) NoHash
>> + (Just (Stub b _), Just (Stub o _)) -> Stub (do o' <- o
>> + b' <- b
>> + return $ overlay b' o') NoHash
>> + (Just x, _) -> x
>> + (_, _) -> error $ "Unexpected case in overlay at get " ++ show n ++ "."
>
> I suppose you know that you'll never get a Nothing from the lookup because you
> get n via listImmediate, which apparently always returns valid indexes.
Yes, the error there is pure paranoia.
Yours,
Petr.
More information about the darcs-users
mailing list