|
8 | 8 | module Ouroboros.Consensus.Util.StreamingLedgerTables where
|
9 | 9 |
|
10 | 10 | import Cardano.Slotting.Slot
|
11 |
| -import Codec.CBOR.Decoding (Decoder) |
| 11 | +import Codec.CBOR.Decoding (Decoder, decodeBreakOr, decodeMapLenIndef) |
12 | 12 | import Codec.CBOR.Encoding (Encoding, encodeBreak, encodeMapLenIndef)
|
13 |
| -import Codec.CBOR.FlatTerm |
14 | 13 | import Codec.CBOR.Read
|
15 | 14 | import Codec.CBOR.Write
|
16 | 15 | import Control.Concurrent.Class.MonadMVar
|
| 16 | +import Control.Monad (unless) |
17 | 17 | import Control.Monad.Class.MonadAsync
|
18 | 18 | import Control.Monad.Class.MonadST
|
19 | 19 | import Control.Monad.Class.MonadSTM
|
20 | 20 | import Control.Monad.Class.MonadThrow
|
| 21 | +import Control.Monad.Except |
| 22 | +import Control.Monad.State.Strict |
21 | 23 | import Data.ByteString (ByteString)
|
22 | 24 | import qualified Data.ByteString as BS
|
23 | 25 | import Data.ByteString.Builder.Extra (defaultChunkSize)
|
24 | 26 | import qualified Data.Map.Strict as Map
|
25 |
| -import Data.MemPack |
26 | 27 | import Data.Proxy
|
27 | 28 | import qualified Data.Set as Set
|
28 | 29 | import qualified Data.Vector as V
|
29 | 30 | import Database.LSMTree
|
30 | 31 | import Ouroboros.Consensus.Ledger.Abstract
|
31 |
| -import Ouroboros.Consensus.Ledger.Tables |
32 | 32 | import Ouroboros.Consensus.Ledger.Tables.Diff
|
33 | 33 | import Ouroboros.Consensus.Storage.LedgerDB.V1.BackingStore.API
|
34 | 34 | import Ouroboros.Consensus.Storage.LedgerDB.V2.LSM
|
35 | 35 | import Ouroboros.Consensus.Storage.LedgerDB.V2.LedgerSeq
|
36 | 36 | import Ouroboros.Network.Block
|
37 | 37 | import Streaming
|
38 | 38 | import qualified Streaming as S
|
39 |
| -import qualified Streaming.Internal as SI |
40 | 39 | import qualified Streaming.Prelude as S
|
41 | 40 | import System.FS.API
|
42 | 41 |
|
@@ -65,120 +64,38 @@ noRemainingBytes s =
|
65 | 64 | Just (BS.null -> True, s') -> noRemainingBytes s'
|
66 | 65 | Just _ -> error "Remaining bytes!"
|
67 | 66 |
|
| 67 | +decodeCbor :: |
| 68 | + (MonadST m, MonadError DeserialiseFailure m) => |
| 69 | + (forall s. Decoder s a) -> |
| 70 | + StateT (Stream (Of ByteString) m r) m a |
| 71 | +decodeCbor dec = |
| 72 | + StateT $ \s -> go s =<< stToIO (deserialiseIncremental dec) |
| 73 | + where |
| 74 | + go s = \case |
| 75 | + Partial k -> |
| 76 | + S.next s >>= \case |
| 77 | + Right (bs, s') -> go s' =<< stToIO (k (Just bs)) |
| 78 | + Left r -> go (pure r) =<< stToIO (k Nothing) |
| 79 | + Done bs _off a -> pure (a, S.yield bs *> s) |
| 80 | + Fail _bs _off err -> throwError err |
| 81 | + |
68 | 82 | yieldCborMapS ::
|
69 | 83 | forall m a b.
|
70 |
| - MonadST m => |
| 84 | + (MonadST m, MonadError DeserialiseFailure m) => |
71 | 85 | (forall s. Decoder s a) ->
|
72 | 86 | (forall s. Decoder s b) ->
|
73 | 87 | Stream (Of ByteString) m () ->
|
74 | 88 | Stream (Of (a, b)) m (Stream (Of ByteString) m ())
|
75 |
| -yieldCborMapS decK decV s = do |
76 |
| - k <- S.lift $ stToIO (deserialiseIncremental decK) |
77 |
| - mbs <- S.lift (S.uncons s) |
78 |
| - case mbs of |
79 |
| - Nothing -> error "Empty stream of bytes" |
80 |
| - Just (bs, s') -> |
81 |
| - case deserialiseFromBytes decodeTermToken (BS.fromStrict bs) of |
82 |
| - Left err -> error $ show err |
83 |
| - Right (bs', TkMapLen n) -> go (Just n) (Left k) $ Right (BS.toStrict bs', s') |
84 |
| - Right (bs', TkMapBegin) -> go Nothing (Left k) $ Right (BS.toStrict bs', s') |
85 |
| - _ -> error "Not a map!" |
| 89 | +yieldCborMapS decK decV = execStateT $ do |
| 90 | + hoist lift $ decodeCbor decodeMapLenIndef |
| 91 | + go |
86 | 92 | where
|
87 |
| - go (Just 0) k mbs = case mbs of |
88 |
| - Left s' -> pure s' |
89 |
| - Right (bs, s') -> pure (S.yield bs *> s') |
90 |
| - go remainingItems k mbs = case (k, mbs) of |
91 |
| - -- We have a partial decoding, awaiting for a bytestring |
92 |
| - |
93 |
| - -- We have read a bytestring from the stream |
94 |
| - (Left (Partial kont), Right (bs, s')) -> do |
95 |
| - k' <- S.lift $ stToIO $ kont $ Just bs |
96 |
| - case k' of |
97 |
| - -- after running the kontinuation, we still require more input, |
98 |
| - -- then read again from the stream |
99 |
| - Partial{} -> go remainingItems (Left k') . maybeToEither s' =<< S.lift (S.uncons s') |
100 |
| - -- We were done with the previous bytestring, so let's |
101 |
| - -- recurse without reading more. |
102 |
| - _ -> go remainingItems (Left k') (Left s') |
103 |
| - |
104 |
| - -- We are in a partial reading, but we were unable to read more |
105 |
| - -- input, so we call `kont` with `Nothing` which will fail. |
106 |
| - (Left (Partial kont), Left s') -> do |
107 |
| - k' <- S.lift $ stToIO $ kont Nothing |
108 |
| - go remainingItems (Left k') (Left s') |
109 |
| - |
110 |
| - -- We have read a bytestring from the stream |
111 |
| - (Right (valK, Partial kont), Right (bs, s')) -> do |
112 |
| - k' <- S.lift $ stToIO $ kont $ Just bs |
113 |
| - case k' of |
114 |
| - -- after running the kontinuation, we still require more input, |
115 |
| - -- then read again from the stream |
116 |
| - Partial{} -> go remainingItems (Right (valK, k')) . maybeToEither s' =<< S.lift (S.uncons s') |
117 |
| - -- We were done with the previous bytestring, so let's |
118 |
| - -- recurse without reading more. |
119 |
| - _ -> go remainingItems (Right (valK, k')) (Left s') |
120 |
| - |
121 |
| - -- We are in a partial reading, but we were unable to read more |
122 |
| - -- input, so we call `kont` with `Nothing` which will fail. |
123 |
| - (Right (valK, Partial kont), Left s') -> do |
124 |
| - k' <- S.lift $ stToIO $ kont Nothing |
125 |
| - go remainingItems (Right (valK, k')) (Left s') |
126 |
| - |
127 |
| - -- We completed a read |
128 |
| - (Left (Done unused _offset val), Left s') -> do |
129 |
| - if BS.null unused |
130 |
| - then |
131 |
| - -- We have no unused bytes, so read another chunk |
132 |
| - S.lift (S.uncons s') >>= \case |
133 |
| - -- If there is no more input, fail because we were expecting a value! |
134 |
| - Nothing -> error "No value!" |
135 |
| - -- Recurse if there is more input |
136 |
| - Just mbs' -> do |
137 |
| - k' <- S.lift $ stToIO (deserialiseIncremental decV) |
138 |
| - go remainingItems (Right (val, k')) $ Right mbs' |
139 |
| - else do |
140 |
| - -- We still have unused bytes, so use those before reading |
141 |
| - -- again. |
142 |
| - k' <- S.lift $ stToIO (deserialiseIncremental decV) |
143 |
| - go remainingItems (Right (val, k')) (Right (unused, s')) |
144 |
| - |
145 |
| - -- We completed a read |
146 |
| - (Right (valK, Done unused _offset val), Left s') -> do |
147 |
| - -- yield the pair |
148 |
| - S.yield (valK, val) |
149 |
| - case remainingItems of |
150 |
| - Just 1 -> pure (S.yield unused *> s') |
151 |
| - _ -> do |
152 |
| - k' <- S.lift $ stToIO (deserialiseIncremental decK) |
153 |
| - if BS.null unused |
154 |
| - then |
155 |
| - -- We have no unused bytes, so read another chunk |
156 |
| - S.lift (S.uncons s') >>= \case |
157 |
| - -- If there is no more input, then we are done! |
158 |
| - Nothing -> |
159 |
| - case remainingItems of |
160 |
| - Just n -> error $ "Missing " ++ show (n - 1) ++ " items!" |
161 |
| - Nothing -> error "Missing a break!" |
162 |
| - -- Recurse if there is more input |
163 |
| - Just mbs' -> do |
164 |
| - go ((\x -> x - 1) <$> remainingItems) (Left k') $ Right mbs' |
165 |
| - else do |
166 |
| - -- We still have unused bytes, so use those before reading |
167 |
| - -- again. |
168 |
| - go ((\x -> x - 1) <$> remainingItems) (Left k') (Right (unused, s')) |
169 |
| - (Left (Done _ _ _), Right _) -> error "unreachable!" |
170 |
| - (Right (_, Done _ _ _), Right _) -> error "unreachable!" |
171 |
| - (Left Fail{}, Right{}) -> error "unreachable!" |
172 |
| - (Right (_, Fail{}), Right{}) -> error "unreachable!" |
173 |
| - (Left (Fail bs _ err), Left s') -> |
174 |
| - case remainingItems of |
175 |
| - Nothing -> case deserialiseFromBytes decodeTermToken (BS.fromStrict bs) of |
176 |
| - Right (bs', TkBreak) -> pure (S.yield (BS.toStrict bs') *> s') |
177 |
| - _ -> error "Break not found!" |
178 |
| - _ -> |
179 |
| - error $ show err |
180 |
| - (Right (_, Fail bs _ err), _) -> |
181 |
| - error $ show err |
| 93 | + go = do |
| 94 | + doBreak <- hoist lift $ decodeCbor decodeBreakOr |
| 95 | + unless doBreak $ do |
| 96 | + kv <- hoist lift $ decodeCbor $ (,) <$> decK <*> decV |
| 97 | + lift $ S.yield kv |
| 98 | + go |
182 | 99 |
|
183 | 100 | maybeToEither :: a -> Maybe b -> Either a b
|
184 | 101 | maybeToEither _ (Just b) = Right b
|
|
0 commit comments