2
2
// SPDX-License-Identifier: Apache-2.0, MIT
3
3
4
4
use std:: convert:: TryInto ;
5
+ use std:: num:: TryFromIntError ;
5
6
6
7
use cid:: Cid ;
7
- use fil_actors_runtime:: { ActorContext , ActorError , Array } ;
8
+ use fil_actors_runtime:: { ActorError , Array } ;
8
9
use fvm_ipld_amt:: Error as AmtError ;
9
10
use fvm_ipld_bitfield:: BitField ;
10
11
use fvm_ipld_blockstore:: Blockstore ;
@@ -18,8 +19,28 @@ pub struct BitFieldQueue<'db, BS> {
18
19
quant : QuantSpec ,
19
20
}
20
21
22
+ #[ derive( thiserror:: Error , Debug ) ]
23
+ pub enum Error < E > {
24
+ #[ error( "amt {0}" ) ]
25
+ Amt ( #[ from] AmtError < E > ) ,
26
+ #[ error( "conversion failure {0}" ) ]
27
+ Int ( #[ from] TryFromIntError ) ,
28
+ #[ error( "bitfield {0}" ) ]
29
+ Bitfield ( #[ from] fvm_ipld_bitfield:: OutOfRangeError ) ,
30
+ }
31
+
32
+ impl < E : std:: error:: Error > From < Error < E > > for ActorError {
33
+ fn from ( e : Error < E > ) -> Self {
34
+ match e {
35
+ Error :: Amt ( e) => e. into ( ) ,
36
+ Error :: Int ( e) => e. into ( ) ,
37
+ Error :: Bitfield ( e) => e. into ( ) ,
38
+ }
39
+ }
40
+ }
41
+
21
42
impl < ' db , BS : Blockstore > BitFieldQueue < ' db , BS > {
22
- pub fn new ( store : & ' db BS , root : & Cid , quant : QuantSpec ) -> Result < Self , AmtError < BS :: Error > > {
43
+ pub fn new ( store : & ' db BS , root : & Cid , quant : QuantSpec ) -> Result < Self , Error < BS :: Error > > {
23
44
Ok ( Self { amt : Array :: load ( root, store) ?, quant } )
24
45
}
25
46
@@ -28,24 +49,17 @@ impl<'db, BS: Blockstore> BitFieldQueue<'db, BS> {
28
49
& mut self ,
29
50
raw_epoch : ChainEpoch ,
30
51
values : & BitField ,
31
- ) -> Result < ( ) , ActorError > {
52
+ ) -> Result < ( ) , Error < BS :: Error > > {
32
53
if values. is_empty ( ) {
33
54
// nothing to do.
34
55
return Ok ( ( ) ) ;
35
56
}
36
57
37
58
let epoch: u64 = self . quant . quantize_up ( raw_epoch) . try_into ( ) ?;
38
59
39
- let bitfield = self
40
- . amt
41
- . get ( epoch)
42
- . with_context ( || format ! ( "failed to lookup queue epoch {}" , epoch) ) ?
43
- . cloned ( )
44
- . unwrap_or_default ( ) ;
60
+ let bitfield = self . amt . get ( epoch) ?. cloned ( ) . unwrap_or_default ( ) ;
45
61
46
- self . amt
47
- . set ( epoch, & bitfield | values)
48
- . with_context ( || format ! ( "failed to set queue epoch {}" , epoch) ) ?;
62
+ self . amt . set ( epoch, & bitfield | values) ?;
49
63
50
64
Ok ( ( ) )
51
65
}
@@ -54,40 +68,36 @@ impl<'db, BS: Blockstore> BitFieldQueue<'db, BS> {
54
68
& mut self ,
55
69
epoch : ChainEpoch ,
56
70
values : impl IntoIterator < Item = u64 > ,
57
- ) -> Result < ( ) , ActorError > {
71
+ ) -> Result < ( ) , Error < BS :: Error > > {
58
72
self . add_to_queue ( epoch, & BitField :: try_from_bits ( values) ?)
59
73
}
60
74
61
75
/// Cut cuts the elements from the bits in the given bitfield out of the queue,
62
76
/// shifting other bits down and removing any newly empty entries.
63
77
///
64
78
/// See the docs on `BitField::cut` to better understand what it does.
65
- pub fn cut ( & mut self , to_cut : & BitField ) -> Result < ( ) , ActorError > {
79
+ pub fn cut ( & mut self , to_cut : & BitField ) -> Result < ( ) , Error < BS :: Error > > {
66
80
let mut epochs_to_remove = Vec :: < u64 > :: new ( ) ;
67
81
68
- self . amt
69
- . for_each_mut ( |epoch, bitfield| {
70
- let bf = bitfield. cut ( to_cut) ;
82
+ self . amt . for_each_mut ( |epoch, bitfield| {
83
+ let bf = bitfield. cut ( to_cut) ;
71
84
72
- if bf. is_empty ( ) {
73
- epochs_to_remove. push ( epoch) ;
74
- } else {
75
- * * bitfield = bf;
76
- }
77
- } )
78
- . context ( "failed to cut from bitfield queue" ) ?;
85
+ if bf. is_empty ( ) {
86
+ epochs_to_remove. push ( epoch) ;
87
+ } else {
88
+ * * bitfield = bf;
89
+ }
90
+ } ) ?;
79
91
80
- self . amt
81
- . batch_delete ( epochs_to_remove, true )
82
- . context ( "failed to remove empty epochs from bitfield queue" ) ?;
92
+ self . amt . batch_delete ( epochs_to_remove, true ) ?;
83
93
84
94
Ok ( ( ) )
85
95
}
86
96
87
97
pub fn add_many_to_queue_values (
88
98
& mut self ,
89
99
values : impl IntoIterator < Item = ( ChainEpoch , u64 ) > ,
90
- ) -> Result < ( ) , ActorError > {
100
+ ) -> Result < ( ) , Error < BS :: Error > > {
91
101
// Pre-quantize to reduce the number of updates.
92
102
let mut quantized_values: Vec < _ > = values
93
103
. into_iter ( )
@@ -112,7 +122,7 @@ impl<'db, BS: Blockstore> BitFieldQueue<'db, BS> {
112
122
113
123
/// Removes and returns all values with keys less than or equal to until.
114
124
/// Modified return value indicates whether this structure has been changed by the call.
115
- pub fn pop_until ( & mut self , until : ChainEpoch ) -> Result < ( BitField , bool ) , ActorError > {
125
+ pub fn pop_until ( & mut self , until : ChainEpoch ) -> Result < ( BitField , bool ) , Error < BS :: Error > > {
116
126
let mut popped_values = BitField :: new ( ) ;
117
127
let mut popped_keys = Vec :: < u64 > :: new ( ) ;
118
128
0 commit comments