@@ -78,33 +78,58 @@ pub fn next_entries_mut(
78
78
cur_hashes : & mut u64 ,
79
79
transactions : Vec < Transaction > ,
80
80
) -> Vec < Entry > {
81
- if transactions. is_empty ( ) {
81
+ // TODO: find a magic number that works better than | ?
82
+ // V
83
+ if transactions. is_empty ( ) || transactions. len ( ) == 1 {
82
84
vec ! [ Entry :: new_mut( start_hash, cur_hashes, transactions, false ) ]
83
85
} else {
84
- let mut chunk_len = transactions. len ( ) ;
86
+ let mut start = 0 ;
87
+ let mut entries = Vec :: new ( ) ;
85
88
86
- // check for fit, make sure they can be serialized
87
- while !Entry :: will_fit ( transactions[ 0 ..chunk_len] . to_vec ( ) ) {
88
- chunk_len /= 2 ;
89
- }
90
-
91
- let mut num_chunks = if transactions. len ( ) % chunk_len == 0 {
92
- transactions. len ( ) / chunk_len
93
- } else {
94
- transactions. len ( ) / chunk_len + 1
95
- } ;
96
-
97
- let mut entries = Vec :: with_capacity ( num_chunks) ;
89
+ while start < transactions. len ( ) {
90
+ let mut chunk_end = transactions. len ( ) ;
91
+ let mut upper = chunk_end;
92
+ let mut lower = start;
93
+ let mut next = chunk_end; // be optimistic that all will fit
98
94
99
- for chunk in transactions. chunks ( chunk_len) {
100
- num_chunks -= 1 ;
95
+ // binary search for how many transactions will fit in an Entry (i.e. a BLOB)
96
+ loop {
97
+ debug ! (
98
+ "chunk_end {}, upper {} lower {} next {} transactions.len() {}" ,
99
+ chunk_end,
100
+ upper,
101
+ lower,
102
+ next,
103
+ transactions. len( )
104
+ ) ;
105
+ if Entry :: will_fit ( transactions[ start..chunk_end] . to_vec ( ) ) {
106
+ next = ( upper + chunk_end) / 2 ;
107
+ lower = chunk_end;
108
+ debug ! (
109
+ "chunk_end {} fits, maybe too well? trying {}" ,
110
+ chunk_end, next
111
+ ) ;
112
+ } else {
113
+ next = ( lower + chunk_end) / 2 ;
114
+ upper = chunk_end;
115
+ debug ! ( "chunk_end {} doesn't fit! trying {}" , chunk_end, next) ;
116
+ }
117
+ // same as last time
118
+ if next == chunk_end {
119
+ debug ! ( "converged on chunk_end {}" , chunk_end) ;
120
+ break ;
121
+ }
122
+ chunk_end = next;
123
+ }
101
124
entries. push ( Entry :: new_mut (
102
125
start_hash,
103
126
cur_hashes,
104
- chunk . to_vec ( ) ,
105
- num_chunks > 0 ,
127
+ transactions [ start..chunk_end ] . to_vec ( ) ,
128
+ transactions . len ( ) - chunk_end > 0 ,
106
129
) ) ;
130
+ start = chunk_end;
107
131
}
132
+
108
133
entries
109
134
}
110
135
}
@@ -217,7 +242,7 @@ mod tests {
217
242
transactions. extend ( large_transactions) ;
218
243
219
244
let entries0 = next_entries ( & id, 0 , transactions. clone ( ) ) ;
220
- assert_eq ! ( entries0. len( ) , 5 ) ;
245
+ assert ! ( entries0. len( ) > 2 ) ;
221
246
assert ! ( entries0[ 0 ] . has_more) ;
222
247
assert ! ( !entries0[ entries0. len( ) - 1 ] . has_more) ;
223
248
assert ! ( entries0. verify( & id) ) ;
0 commit comments