Skip to content

Commit 339959a

Browse files
committed
Return the last read key in LMDB backend
1 parent a4c18c9 commit 339959a

File tree

18 files changed

+303
-232
lines changed

18 files changed

+303
-232
lines changed

cabal.project

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ index-state:
1616
-- Bump this if you need newer packages from Hackage
1717
, hackage.haskell.org 2025-07-22T09:13:54Z
1818
-- Bump this if you need newer packages from CHaP
19-
, cardano-haskell-packages 2025-08-06T10:58:15Z
19+
, cardano-haskell-packages 2025-08-21T09:41:03Z
2020

2121
packages:
2222
ouroboros-consensus

flake.lock

Lines changed: 21 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!--
2+
A new scriv changelog fragment.
3+
4+
Uncomment the section that is right (remove the HTML comment wrapper).
5+
For top level release notes, leave all the headers commented out.
6+
-->
7+
8+
<!--
9+
### Patch
10+
11+
- A bullet item for the Patch category.
12+
13+
-->
14+
<!--
15+
### Non-Breaking
16+
17+
- A bullet item for the Non-Breaking category.
18+
19+
-->
20+
21+
### Breaking
22+
23+
- `forkerRangeRead` now returns also the maximal key found in the backend.

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Storage/LedgerDB/Forker.hs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ import Control.Monad.Except
6666
import Control.Monad.Reader (ReaderT (..))
6767
import Control.Monad.Trans (MonadTrans (..))
6868
import Control.ResourceRegistry
69+
import Data.Bifunctor (first)
6970
import Data.Kind
7071
import Data.Set (Set)
7172
import qualified Data.Set as Set
@@ -105,7 +106,7 @@ data Forker m l blk = Forker
105106

106107
forkerReadTables :: !(LedgerTables l KeysMK -> m (LedgerTables l ValuesMK))
107108
-- ^ Read ledger tables from disk.
108-
, forkerRangeReadTables :: !(RangeQueryPrevious l -> m (LedgerTables l ValuesMK))
109+
, forkerRangeReadTables :: !(RangeQueryPrevious l -> m (LedgerTables l ValuesMK, Maybe (TxIn l)))
109110
-- ^ Range-read ledger tables from disk.
110111
--
111112
-- This range read will return as many values as the 'QueryBatchSize' that
@@ -206,7 +207,8 @@ ledgerStateReadOnlyForker frk =
206207
ReadOnlyForker
207208
{ roforkerClose = roforkerClose
208209
, roforkerReadTables = fmap castLedgerTables . roforkerReadTables . castLedgerTables
209-
, roforkerRangeReadTables = fmap castLedgerTables . roforkerRangeReadTables . castRangeQueryPrevious
210+
, roforkerRangeReadTables =
211+
fmap (first castLedgerTables) . roforkerRangeReadTables . castRangeQueryPrevious
210212
, roforkerGetLedgerState = ledgerState <$> roforkerGetLedgerState
211213
, roforkerReadStatistics = roforkerReadStatistics
212214
}
@@ -239,7 +241,7 @@ data ReadOnlyForker m l blk = ReadOnlyForker
239241
-- ^ See 'forkerClose'
240242
, roforkerReadTables :: !(LedgerTables l KeysMK -> m (LedgerTables l ValuesMK))
241243
-- ^ See 'forkerReadTables'
242-
, roforkerRangeReadTables :: !(RangeQueryPrevious l -> m (LedgerTables l ValuesMK))
244+
, roforkerRangeReadTables :: !(RangeQueryPrevious l -> m (LedgerTables l ValuesMK, Maybe (TxIn l)))
243245
-- ^ See 'forkerRangeReadTables'.
244246
, roforkerGetLedgerState :: !(STM m (l EmptyMK))
245247
-- ^ See 'forkerGetLedgerState'

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Storage/LedgerDB/V1/BackingStore/API.hs

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ module Ouroboros.Consensus.Storage.LedgerDB.V1.BackingStore.API
5858
) where
5959

6060
import Cardano.Slotting.Slot (SlotNo, WithOrigin (..))
61+
import Data.Bifunctor
6162
import Data.Kind
6263
import GHC.Generics
6364
import NoThunks.Class (OnlyCheckWhnfNamed (..))
@@ -93,7 +94,7 @@ data DiffsToFlush l = DiffsToFlush
9394
-- considered as "last flushed" in the kept 'DbChangelog'
9495
}
9596

96-
data BackingStore m keys values diff = BackingStore
97+
data BackingStore m keys key values diff = BackingStore
9798
{ bsClose :: !(m ())
9899
-- ^ Close the backing store
99100
--
@@ -107,7 +108,7 @@ data BackingStore m keys values diff = BackingStore
107108
--
108109
-- The destination path must not already exist. After this operation, it
109110
-- will be a directory.
110-
, bsValueHandle :: !(m (BackingStoreValueHandle m keys values))
111+
, bsValueHandle :: !(m (BackingStoreValueHandle m keys key values))
111112
-- ^ Open a 'BackingStoreValueHandle' capturing the current value of the
112113
-- entire database
113114
, bsWrite :: !(SlotNo -> WriteHint diff -> diff -> m ())
@@ -118,14 +119,15 @@ data BackingStore m keys values diff = BackingStore
118119
}
119120

120121
deriving via
121-
OnlyCheckWhnfNamed "BackingStore" (BackingStore m keys values diff)
122+
OnlyCheckWhnfNamed "BackingStore" (BackingStore m keys key values diff)
122123
instance
123-
NoThunks (BackingStore m keys values diff)
124+
NoThunks (BackingStore m keys key values diff)
124125

125126
type LedgerBackingStore m l =
126127
BackingStore
127128
m
128129
(LedgerTables l KeysMK)
130+
(TxIn l)
129131
(LedgerTables l ValuesMK)
130132
(LedgerTables l DiffMK)
131133

@@ -157,15 +159,15 @@ data InitFrom values
157159
-- The performance cost is usually minimal unless this handle is held open too
158160
-- long. We expect clients of the 'BackingStore' to not retain handles for a
159161
-- long time.
160-
data BackingStoreValueHandle m keys values = BackingStoreValueHandle
162+
data BackingStoreValueHandle m keys key values = BackingStoreValueHandle
161163
{ bsvhAtSlot :: !(WithOrigin SlotNo)
162164
-- ^ At which slot this handle was created
163165
, bsvhClose :: !(m ())
164166
-- ^ Close the handle
165167
--
166168
-- Other methods throw exceptions if called on a closed handle. 'bsvhClose'
167169
-- itself is idempotent.
168-
, bsvhRangeRead :: !(ReadHint values -> RangeQuery keys -> m values)
170+
, bsvhRangeRead :: !(ReadHint values -> RangeQuery keys -> m (values, Maybe key))
169171
-- ^ See 'RangeQuery'
170172
, bsvhReadAll :: !(ReadHint values -> m values)
171173
-- ^ Costly read all operation, not to be used in Consensus but only in
@@ -180,14 +182,15 @@ data BackingStoreValueHandle m keys values = BackingStoreValueHandle
180182
}
181183

182184
deriving via
183-
OnlyCheckWhnfNamed "BackingStoreValueHandle" (BackingStoreValueHandle m keys values)
185+
OnlyCheckWhnfNamed "BackingStoreValueHandle" (BackingStoreValueHandle m keys key values)
184186
instance
185-
NoThunks (BackingStoreValueHandle m keys values)
187+
NoThunks (BackingStoreValueHandle m keys key values)
186188

187189
type LedgerBackingStoreValueHandle m l =
188190
BackingStoreValueHandle
189191
m
190192
(LedgerTables l KeysMK)
193+
(TxIn l)
191194
(LedgerTables l ValuesMK)
192195

193196
type BackingStoreValueHandle' m blk = LedgerBackingStoreValueHandle m (ExtLedgerState blk)
@@ -196,15 +199,16 @@ castBackingStoreValueHandle ::
196199
(Functor m, ReadHint values ~ ReadHint values') =>
197200
(values -> values') ->
198201
(keys' -> keys) ->
199-
BackingStoreValueHandle m keys values ->
200-
BackingStoreValueHandle m keys' values'
201-
castBackingStoreValueHandle f g bsvh =
202+
(key -> key') ->
203+
BackingStoreValueHandle m keys key values ->
204+
BackingStoreValueHandle m keys' key' values'
205+
castBackingStoreValueHandle f g h bsvh =
202206
BackingStoreValueHandle
203207
{ bsvhAtSlot
204208
, bsvhClose
205209
, bsvhReadAll = \rhint -> f <$> bsvhReadAll rhint
206210
, bsvhRangeRead = \rhint (RangeQuery prev count) ->
207-
fmap f . bsvhRangeRead rhint $ RangeQuery (fmap g prev) count
211+
fmap (second (fmap h) . first f) . bsvhRangeRead rhint $ RangeQuery (fmap g prev) count
208212
, bsvhRead = \rhint -> fmap f . bsvhRead rhint . g
209213
, bsvhStat
210214
}
@@ -221,7 +225,7 @@ castBackingStoreValueHandle f g bsvh =
221225
-- | A combination of 'bsValueHandle' and 'bsvhRead'
222226
bsRead ::
223227
MonadThrow m =>
224-
BackingStore m keys values diff ->
228+
BackingStore m keys key values diff ->
225229
ReadHint values ->
226230
keys ->
227231
m (WithOrigin SlotNo, values)
@@ -231,16 +235,16 @@ bsRead store rhint keys = withBsValueHandle store $ \vh -> do
231235

232236
bsReadAll ::
233237
MonadThrow m =>
234-
BackingStore m keys values diff ->
238+
BackingStore m keys key values diff ->
235239
ReadHint values ->
236240
m values
237241
bsReadAll store rhint = withBsValueHandle store $ \vh -> bsvhReadAll vh rhint
238242

239243
-- | A 'IOLike.bracket'ed 'bsValueHandle'
240244
withBsValueHandle ::
241245
MonadThrow m =>
242-
BackingStore m keys values diff ->
243-
(BackingStoreValueHandle m keys values -> m a) ->
246+
BackingStore m keys key values diff ->
247+
(BackingStoreValueHandle m keys key values -> m a) ->
244248
m a
245249
withBsValueHandle store =
246250
bracket

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Storage/LedgerDB/V1/BackingStore/Impl/InMemory.hs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -247,12 +247,14 @@ newInMemoryBackingStore tracer (SnapshotsFS (SomeHasFS fs)) initialization = do
247247
rangeRead ::
248248
RangeQuery (LedgerTables l KeysMK) ->
249249
LedgerTables l ValuesMK ->
250-
LedgerTables l ValuesMK
251-
rangeRead rq values = case rqPrev rq of
252-
Nothing ->
253-
ltmap (rangeRead0' (rqCount rq)) values
254-
Just keys ->
255-
ltliftA2 (rangeRead' (rqCount rq)) keys values
250+
(LedgerTables l ValuesMK, Maybe (TxIn l))
251+
rangeRead rq values =
252+
let vs@(LedgerTables (ValuesMK m)) = case rqPrev rq of
253+
Nothing ->
254+
ltmap (rangeRead0' (rqCount rq)) values
255+
Just keys ->
256+
ltliftA2 (rangeRead' (rqCount rq)) keys values
257+
in (vs, fst <$> Map.lookupMax m)
256258

257259
rangeRead0' ::
258260
Int ->

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Storage/LedgerDB/V1/BackingStore/Impl/LMDB.hs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import Control.Monad (forM_, unless, void, when)
3636
import qualified Control.Monad.Class.MonadSTM as IOLike
3737
import Control.Monad.IO.Class (MonadIO (liftIO))
3838
import qualified Control.Tracer as Trace
39+
import Data.Bifunctor (first)
3940
import Data.Functor (($>), (<&>))
4041
import Data.Functor.Contravariant ((>$<))
4142
import Data.Map (Map)
@@ -189,12 +190,12 @@ rangeRead ::
189190
API.RangeQuery (LedgerTables l KeysMK) ->
190191
idx ->
191192
LMDBMK (TxIn l) (TxOut l) ->
192-
LMDB.Transaction mode (ValuesMK (TxIn l) (TxOut l))
193+
LMDB.Transaction mode (ValuesMK (TxIn l) (TxOut l), Maybe (TxIn l))
193194
rangeRead rq st dbMK =
194-
ValuesMK <$> case ksMK of
195+
first ValuesMK <$> case ksMK of
195196
Nothing -> runCursorHelper Nothing
196197
Just (LedgerTables (KeysMK ks)) -> case Set.lookupMax ks of
197-
Nothing -> pure mempty
198+
Nothing -> pure (mempty, Nothing)
198199
Just lastExcludedKey ->
199200
runCursorHelper $ Just (lastExcludedKey, LMDB.Cursor.Exclusive)
200201
where
@@ -205,11 +206,11 @@ rangeRead rq st dbMK =
205206
runCursorHelper ::
206207
Maybe (TxIn l, LMDB.Cursor.Bound) ->
207208
-- \^ Lower bound on read range
208-
LMDB.Transaction mode (Map (TxIn l) (TxOut l))
209+
LMDB.Transaction mode (Map (TxIn l) (TxOut l), Maybe (TxIn l))
209210
runCursorHelper lb =
210211
Bridge.runCursorAsTransaction'
211212
st
212-
(LMDB.Cursor.cgetMany lb count)
213+
(LMDB.Cursor.cgetManyAndLast lb count)
213214
db
214215

215216
initLMDBTable ::
@@ -631,7 +632,7 @@ mkLMDBBackingStoreValueHandle db = do
631632
bsvhRangeRead ::
632633
l EmptyMK ->
633634
API.RangeQuery (LedgerTables l KeysMK) ->
634-
m (LedgerTables l ValuesMK)
635+
m (LedgerTables l ValuesMK, Maybe (TxIn l))
635636
bsvhRangeRead st rq =
636637
Status.withReadAccess dbStatusLock (throwIO LMDBErrClosed) $ do
637638
Status.withReadAccess vhStatusLock (throwIO (LMDBErrNoValueHandle vhId)) $ do
@@ -640,7 +641,7 @@ mkLMDBBackingStoreValueHandle db = do
640641
liftIO $
641642
TrH.submitReadOnly trh $
642643
let dbMK = getLedgerTables dbBackingTables
643-
in LedgerTables <$> rangeRead rq st dbMK
644+
in first LedgerTables <$> rangeRead rq st dbMK
644645
Trace.traceWith tracer API.BSVHRangeRead
645646
pure res
646647

0 commit comments

Comments
 (0)