mirror of https://github.com/voidlizard/hbs2
wip20
This commit is contained in:
parent
86a73fbe67
commit
5b73884f00
|
@ -442,11 +442,6 @@ data ExportState =
|
||||||
| ExportStart
|
| ExportStart
|
||||||
| ExportExit
|
| ExportExit
|
||||||
|
|
||||||
data WState =
|
|
||||||
WStart
|
|
||||||
| WNextSBlock
|
|
||||||
| WReadSBlock Int HashRef
|
|
||||||
| WProcessCBlock Int HashRef
|
|
||||||
|
|
||||||
data EOp =
|
data EOp =
|
||||||
EGitObject GitObjectType GitHash (Maybe GitTreeEntry) ByteString
|
EGitObject GitObjectType GitHash (Maybe GitTreeEntry) ByteString
|
||||||
|
@ -880,6 +875,81 @@ readCBlock sto hash action = do
|
||||||
-- pure True
|
-- pure True
|
||||||
|
|
||||||
|
|
||||||
|
data WState =
|
||||||
|
WStart
|
||||||
|
| WNextSBlock
|
||||||
|
| WReadSBlock Int HashRef
|
||||||
|
| WProcessCBlock Int HashRef
|
||||||
|
|
||||||
|
traverseToCBlock :: forall m . MonadIO m
|
||||||
|
=> AnyStorage
|
||||||
|
-> HashRef
|
||||||
|
-> ( Int -> HashRef -> [HashRef] -> m () )
|
||||||
|
-> m ()
|
||||||
|
traverseToCBlock sto cblock action = do
|
||||||
|
|
||||||
|
q <- newTVarIO ( HPSQ.empty @HashRef @Int @() )
|
||||||
|
done <- newTVarIO ( mempty :: HashSet HashRef )
|
||||||
|
cache <- newCacheFixedHPSQ 1000
|
||||||
|
|
||||||
|
flip fix WStart $ \next -> \case
|
||||||
|
WStart -> do
|
||||||
|
atomically $ modifyTVar q (HPSQ.insert cblock 1 ())
|
||||||
|
next WNextSBlock
|
||||||
|
|
||||||
|
WNextSBlock -> do
|
||||||
|
|
||||||
|
blk' <- atomically $ stateTVar q $ HPSQ.alterMin \case
|
||||||
|
Nothing -> (Nothing, Nothing)
|
||||||
|
Just (k,p,_) -> (Just (k,p), Nothing)
|
||||||
|
|
||||||
|
debug $ "WNextSBlock" <+> pretty blk'
|
||||||
|
|
||||||
|
maybe1 blk' none $ \(k,p) -> do
|
||||||
|
next (WReadSBlock p k)
|
||||||
|
|
||||||
|
WReadSBlock prio h -> do
|
||||||
|
debug $ "WReadSBlock" <+> pretty h
|
||||||
|
|
||||||
|
sections <- cached cache h $ S.toList_ (readCBlock sto h S.yield)
|
||||||
|
|
||||||
|
for_ sections $ \case
|
||||||
|
CBlockData _ -> none
|
||||||
|
CBlockParents p -> do
|
||||||
|
debug $ "parents" <+> pretty p
|
||||||
|
next =<< atomically do
|
||||||
|
d <- readTVar done
|
||||||
|
for_ (zip [1..] p) $ \(i,x) -> do
|
||||||
|
unless (HS.member x d) do
|
||||||
|
modifyTVar q (HPSQ.insert x (prio-i) ())
|
||||||
|
|
||||||
|
let hDone = HS.member h d
|
||||||
|
|
||||||
|
unless hDone do
|
||||||
|
modifyTVar q (HPSQ.insert h prio ())
|
||||||
|
|
||||||
|
qq <- readTVar q
|
||||||
|
if not (any (`HPSQ.member` qq) p) && not hDone then do
|
||||||
|
pure $ WProcessCBlock prio h
|
||||||
|
else do
|
||||||
|
pure WNextSBlock
|
||||||
|
|
||||||
|
WProcessCBlock i h -> do
|
||||||
|
what <- cached cache h $ S.toList_ (readCBlock sto h S.yield)
|
||||||
|
atomically $ modifyTVar done ( HS.insert h )
|
||||||
|
uncache cache h
|
||||||
|
|
||||||
|
debug $ "process cblock" <+> pretty h
|
||||||
|
|
||||||
|
for_ what \case
|
||||||
|
CBlockParents{} -> do
|
||||||
|
none
|
||||||
|
|
||||||
|
CBlockData hrefs -> do
|
||||||
|
action i h hrefs
|
||||||
|
|
||||||
|
next $ WNextSBlock
|
||||||
|
|
||||||
|
|
||||||
theDict :: forall m . ( HBS2GitPerks m
|
theDict :: forall m . ( HBS2GitPerks m
|
||||||
, HasClientAPI PeerAPI UNIX m
|
, HasClientAPI PeerAPI UNIX m
|
||||||
|
@ -966,67 +1036,8 @@ theDict = do
|
||||||
|
|
||||||
sto <- getStorage
|
sto <- getStorage
|
||||||
|
|
||||||
q <- newTVarIO ( HPSQ.empty @HashRef @Int @() )
|
traverseToCBlock sto cblock $ \i h _ -> do
|
||||||
done <- newTVarIO ( mempty :: HashSet HashRef )
|
debug $ green "process cblock data" <+> pretty i <+> pretty h
|
||||||
cache <- newCacheFixedHPSQ 1000
|
|
||||||
|
|
||||||
flip fix WStart $ \next -> \case
|
|
||||||
WStart -> do
|
|
||||||
atomically $ modifyTVar q (HPSQ.insert cblock 1 ())
|
|
||||||
next WNextSBlock
|
|
||||||
|
|
||||||
WNextSBlock -> do
|
|
||||||
|
|
||||||
blk' <- atomically $ stateTVar q $ HPSQ.alterMin \case
|
|
||||||
Nothing -> (Nothing, Nothing)
|
|
||||||
Just (k,p,_) -> (Just (k,p), Nothing)
|
|
||||||
|
|
||||||
debug $ "WNextSBlock" <+> pretty blk'
|
|
||||||
|
|
||||||
maybe1 blk' none $ \(k,p) -> do
|
|
||||||
next (WReadSBlock p k)
|
|
||||||
|
|
||||||
WReadSBlock prio h -> do
|
|
||||||
debug $ "WReadSBlock" <+> pretty h
|
|
||||||
|
|
||||||
sections <- cached cache h $ S.toList_ (readCBlock sto h S.yield)
|
|
||||||
|
|
||||||
for_ sections $ \case
|
|
||||||
CBlockData _ -> none
|
|
||||||
CBlockParents p -> do
|
|
||||||
debug $ "parents" <+> pretty p
|
|
||||||
next =<< atomically do
|
|
||||||
d <- readTVar done
|
|
||||||
for_ (zip [1..] p) $ \(i,x) -> do
|
|
||||||
unless (HS.member x d) do
|
|
||||||
modifyTVar q (HPSQ.insert x (prio-i) ())
|
|
||||||
|
|
||||||
let hDone = HS.member h d
|
|
||||||
|
|
||||||
unless hDone do
|
|
||||||
modifyTVar q (HPSQ.insert h prio ())
|
|
||||||
|
|
||||||
qq <- readTVar q
|
|
||||||
if not (any (`HPSQ.member` qq) p) && not hDone then do
|
|
||||||
pure $ WProcessCBlock prio h
|
|
||||||
else do
|
|
||||||
pure WNextSBlock
|
|
||||||
|
|
||||||
WProcessCBlock _ h -> do
|
|
||||||
what <- cached cache h $ S.toList_ (readCBlock sto h S.yield)
|
|
||||||
atomically $ modifyTVar done ( HS.insert h )
|
|
||||||
uncache cache h
|
|
||||||
|
|
||||||
debug $ "process cblock" <+> pretty h
|
|
||||||
|
|
||||||
for_ what \case
|
|
||||||
CBlockParents{} -> do
|
|
||||||
none
|
|
||||||
|
|
||||||
CBlockData{} -> do
|
|
||||||
debug $ green "process cblock data" <+> pretty h
|
|
||||||
|
|
||||||
next $ WNextSBlock
|
|
||||||
|
|
||||||
_ -> throwIO (BadFormException @C nil)
|
_ -> throwIO (BadFormException @C nil)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue