1- use std:: { borrow:: Cow , marker:: PhantomData } ;
1+ use std:: { borrow:: Cow , marker:: PhantomData , sync :: Arc } ;
22
33use libmdbx:: { TransactionKind , WriteFlags , RO , RW } ;
44use nimiq_database_value:: { AsDatabaseBytes , FromDatabaseValue } ;
55
66use super :: { DbKvPair , IntoIter } ;
7- use crate :: traits:: { ReadCursor , WriteCursor } ;
7+ use crate :: {
8+ metrics:: { DatabaseEnvMetrics , Operation } ,
9+ traits:: { ReadCursor , WriteCursor } ,
10+ } ;
811
912/// A cursor for navigating the entries within a table.
1013/// Wraps the libmdbx cursor so that we only expose our own methods.
1114pub struct MdbxCursor < ' txn , K : TransactionKind > {
1215 cursor : libmdbx:: Cursor < ' txn , K > ,
16+ metrics : Option < Arc < DatabaseEnvMetrics > > ,
17+ table_name : String ,
1318}
1419/// Instantiation of the `MdbxCursor` for read transactions.
1520pub type MdbxReadCursor < ' txn > = MdbxCursor < ' txn , RO > ;
@@ -20,8 +25,33 @@ impl<'txn, Kind> MdbxCursor<'txn, Kind>
2025where
2126 Kind : TransactionKind ,
2227{
23- pub ( crate ) fn new ( cursor : libmdbx:: Cursor < ' txn , Kind > ) -> Self {
24- MdbxCursor { cursor }
28+ pub ( crate ) fn new (
29+ table_name : & str ,
30+ cursor : libmdbx:: Cursor < ' txn , Kind > ,
31+ metrics : Option < Arc < DatabaseEnvMetrics > > ,
32+ ) -> Self {
33+ MdbxCursor {
34+ table_name : table_name. to_string ( ) ,
35+ cursor,
36+ metrics,
37+ }
38+ }
39+
40+ /// If `self.metrics` is `Some(...)`, record a metric with the provided operation and value
41+ /// size.
42+ ///
43+ /// Otherwise, just execute the closure.
44+ fn execute_with_operation_metric < R > (
45+ & mut self ,
46+ operation : Operation ,
47+ value_size : Option < usize > ,
48+ f : impl FnOnce ( & mut Self ) -> R ,
49+ ) -> R {
50+ if let Some ( metrics) = self . metrics . as_ref ( ) . cloned ( ) {
51+ metrics. record_operation ( & self . table_name . clone ( ) , operation, value_size, || f ( self ) )
52+ } else {
53+ f ( self )
54+ }
2555 }
2656}
2757
@@ -246,13 +276,17 @@ where
246276{
247277 fn clone ( & self ) -> Self {
248278 Self {
279+ table_name : self . table_name . clone ( ) ,
249280 cursor : self . cursor . clone ( ) ,
281+ metrics : self . metrics . as_ref ( ) . cloned ( ) ,
250282 }
251283 }
252284}
253285
254286impl < ' txn > WriteCursor < ' txn > for MdbxWriteCursor < ' txn > {
255287 fn remove ( & mut self ) {
256- self . cursor . del ( WriteFlags :: empty ( ) ) . unwrap ( ) ;
288+ self . execute_with_operation_metric ( Operation :: CursorDeleteCurrent , None , |cursor| {
289+ cursor. cursor . del ( WriteFlags :: empty ( ) ) . unwrap ( ) ;
290+ } ) ;
257291 }
258292}
0 commit comments