Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.

Commit 33bd122

Browse files
committed
make next_entries() smarter about fitting Transactions into a Blob
1 parent 195098c commit 33bd122

File tree

1 file changed

+44
-19
lines changed

1 file changed

+44
-19
lines changed

src/ledger.rs

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -78,33 +78,58 @@ pub fn next_entries_mut(
7878
cur_hashes: &mut u64,
7979
transactions: Vec<Transaction>,
8080
) -> 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 {
8284
vec![Entry::new_mut(start_hash, cur_hashes, transactions, false)]
8385
} else {
84-
let mut chunk_len = transactions.len();
86+
let mut start = 0;
87+
let mut entries = Vec::new();
8588

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
9894

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+
}
101124
entries.push(Entry::new_mut(
102125
start_hash,
103126
cur_hashes,
104-
chunk.to_vec(),
105-
num_chunks > 0,
127+
transactions[start..chunk_end].to_vec(),
128+
transactions.len() - chunk_end > 0,
106129
));
130+
start = chunk_end;
107131
}
132+
108133
entries
109134
}
110135
}
@@ -217,7 +242,7 @@ mod tests {
217242
transactions.extend(large_transactions);
218243

219244
let entries0 = next_entries(&id, 0, transactions.clone());
220-
assert_eq!(entries0.len(), 5);
245+
assert!(entries0.len() > 2);
221246
assert!(entries0[0].has_more);
222247
assert!(!entries0[entries0.len() - 1].has_more);
223248
assert!(entries0.verify(&id));

0 commit comments

Comments
 (0)