Skip to content

Commit d87cc5b

Browse files
committed
Correcting the rotate_nested_vector
- renamed for better expression of what it does - updated the doc string of the function to not reference zip - removed the limitation of hints returned, allowing the caller to set the number of items retrieved
1 parent 7398b44 commit d87cc5b

File tree

1 file changed

+41
-52
lines changed

1 file changed

+41
-52
lines changed

lightning-invoice/src/utils.rs

Lines changed: 41 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,9 @@ where
203203
invoice = invoice.amount_milli_satoshis(amt);
204204
}
205205

206-
for route_hint in select_phantom_hints(amt_msat, phantom_route_hints, logger) {
206+
const MAX_HINTS: usize = 3;
207+
208+
for route_hint in select_phantom_hints(amt_msat, phantom_route_hints, logger).take(MAX_HINTS) {
207209
invoice = invoice.private_route(route_hint);
208210
}
209211

@@ -268,46 +270,35 @@ where
268270
// the hints across our real nodes we add one hint from each in turn until no node has any hints
269271
// left (if one node has more hints than any other, these will accumulate at the end of the
270272
// vector).
271-
const MAX_HINTS: usize = 3;
272-
273-
zip_nested_vectors(phantom_hints, MAX_HINTS)
273+
rotate_nested_vectors(phantom_hints)
274274

275275
}
276276

277-
// Zip multiple nested vectors
278-
// Similar to the zip method on a vector, it combines the vectors by index - zero index comes first
279-
// then second, etc.
280-
// The difference is that this function handles many or just one vector, whereas the builtin method
281-
// works on just two vectors.
282-
fn zip_nested_vectors<T: Clone>(vecs: Vec<Vec<T>>, result_size: usize) -> impl Iterator<Item = T> {
277+
// Draw items iteratively from multiple nested vectors. The items are retrieved by index and
278+
// rotates through the vectors - first the zero index then the first index then second index, etc.
279+
fn rotate_nested_vectors<T: Clone>(vecs: Vec<Vec<T>>) -> impl Iterator<Item = T> {
283280
let max_vector_length: usize = vecs.iter().map(|x| x.len()).max().unwrap();
284281
let mut hint_index = 0;
285282
let mut vector_index = 0;
286283
let number_inner_vectors: usize = vecs.len();
287-
let mut total_hints_returned = 0;
288284

289285
core::iter::from_fn(move || loop {
290-
let return_value = loop {
291-
if total_hints_returned == result_size || hint_index == max_vector_length {
292-
break None;
293-
};
294-
let hint_value =
295-
if vecs[vector_index].len() != 0 && vecs[vector_index].len() > hint_index {
296-
Some(vecs[vector_index][hint_index].clone())
297-
} else {
298-
None // no value retrieved - continue looping
299-
};
300-
vector_index += 1;
301-
if hint_index < max_vector_length && vector_index == number_inner_vectors {
302-
vector_index = 0;
303-
hint_index += 1;
304-
};
305-
if !hint_value.is_none() {
306-
total_hints_returned += 1;
307-
break hint_value;
308-
};
286+
if hint_index == max_vector_length {
287+
return None;
288+
};
289+
let hint_value = if vecs[vector_index].len() != 0 && vecs[vector_index].len() > hint_index {
290+
Some(vecs[vector_index][hint_index].clone())
291+
} else {
292+
None // no value retrieved - continue looping
293+
};
294+
vector_index += 1;
295+
if hint_index < max_vector_length && vector_index == number_inner_vectors {
296+
vector_index = 0;
297+
hint_index += 1;
298+
};
299+
if !hint_value.is_none() {
300+
return hint_value;
309301
};
310-
return return_value;
311302
})
312303
}
313304

@@ -796,7 +787,7 @@ mod test {
796787
use lightning::routing::router::{PaymentParameters, RouteParameters};
797788
use lightning::util::test_utils;
798789
use lightning::util::config::UserConfig;
799-
use crate::utils::{create_invoice_from_channelmanager_and_duration_since_epoch, zip_nested_vectors};
790+
use crate::utils::{create_invoice_from_channelmanager_and_duration_since_epoch, rotate_nested_vectors};
800791
use std::collections::HashSet;
801792

802793
#[test]
@@ -1909,60 +1900,58 @@ mod test {
19091900

19101901
#[test]
19111902
fn test_zip_nested_vectors() {
1912-
const TEST_RESULT_SIZE: usize = 3;
1913-
19141903
// two nested vectors
19151904
let a = vec![vec!["a0", "b0", "c0"], vec!["a1", "b1"]];
1916-
let result = zip_nested_vectors(a, TEST_RESULT_SIZE).collect::<Vec<_>>();
1905+
let result = rotate_nested_vectors(a).collect::<Vec<_>>();
19171906

1918-
let expected = vec!["a0", "a1", "b0"];
1907+
let expected = vec!["a0", "a1", "b0", "b1", "c0"];
19191908
assert_eq!(expected, result);
19201909

19211910
// test single nested vector
19221911
let a = vec![vec!["a0", "b0", "c0"]];
1923-
let result = zip_nested_vectors(a, TEST_RESULT_SIZE).collect::<Vec<_>>();
1912+
let result = rotate_nested_vectors(a).collect::<Vec<_>>();
19241913

19251914
let expected = vec!["a0", "b0", "c0"];
19261915
assert_eq!(expected, result);
19271916

19281917
// test second vector with only one element
19291918
let a = vec![vec!["a0", "b0", "c0"], vec!["a1"]];
1930-
let result = zip_nested_vectors(a, TEST_RESULT_SIZE).collect::<Vec<_>>();
1919+
let result = rotate_nested_vectors(a).collect::<Vec<_>>();
19311920

1932-
let expected = vec!["a0", "a1", "b0"];
1921+
let expected = vec!["a0", "a1", "b0", "c0"];
19331922
assert_eq!(expected, result);
19341923

19351924
// test three nestend vectors
19361925
let a = vec![vec!["a0"], vec!["a1", "b1", "c1"], vec!["a2"]];
1937-
let result = zip_nested_vectors(a, TEST_RESULT_SIZE).collect::<Vec<_>>();
1926+
let result = rotate_nested_vectors(a).collect::<Vec<_>>();
19381927

1939-
let expected = vec!["a0", "a1", "a2"];
1928+
let expected = vec!["a0", "a1", "a2", "b1", "c1"];
19401929
assert_eq!(expected, result);
19411930

19421931
// test single nested vector with a single value
19431932
let a = vec![vec!["a0"]];
1944-
let result = zip_nested_vectors(a, TEST_RESULT_SIZE).collect::<Vec<_>>();
1933+
let result = rotate_nested_vectors(a).collect::<Vec<_>>();
19451934

19461935
let expected = vec!["a0"];
19471936
assert_eq!(expected, result);
19481937

19491938
// test single empty nested vector
19501939
let a:Vec<Vec<&str>> = vec![vec![]];
1951-
let result = zip_nested_vectors(a, TEST_RESULT_SIZE).collect::<Vec<_>>();
1940+
let result = rotate_nested_vectors(a).collect::<Vec<_>>();
19521941
let expected:Vec<&str> = vec![];
19531942

19541943
assert_eq!(expected, result);
19551944

19561945
// test first nested vector is empty
19571946
let a = vec![vec![], vec!["a1", "b1", "c1"]];
1958-
let result = zip_nested_vectors(a, TEST_RESULT_SIZE).collect::<Vec<_>>();
1947+
let result = rotate_nested_vectors(a).collect::<Vec<_>>();
19591948

19601949
let expected = vec!["a1", "b1", "c1"];
19611950
assert_eq!(expected, result);
19621951

19631952
// test two empty vectors
19641953
let a:Vec<Vec<&str>> = vec![vec![], vec![]];
1965-
let result = zip_nested_vectors(a, TEST_RESULT_SIZE).collect::<Vec<_>>();
1954+
let result = rotate_nested_vectors(a).collect::<Vec<_>>();
19661955

19671956
let expected:Vec<&str> = vec![];
19681957
assert_eq!(expected, result);
@@ -1974,21 +1963,21 @@ mod test {
19741963
vec!["a1", "b1", "c1"],
19751964
vec!["a2", "b2", "c2"],
19761965
];
1977-
let result = zip_nested_vectors(a, TEST_RESULT_SIZE).collect::<Vec<_>>();
1966+
let result = rotate_nested_vectors(a).collect::<Vec<_>>();
19781967

1979-
let expected = vec!["a0", "a1", "a2"];
1968+
let expected = vec!["a0", "a1", "a2", "b0", "b1", "b2", "c0", "c1", "c2"];
19801969
assert_eq!(expected, result);
19811970

19821971
// test a filled vector between two empty vectors
19831972
let a = vec![vec![], vec!["a1", "b1", "c1"], vec![]];
1984-
let result = zip_nested_vectors(a, TEST_RESULT_SIZE).collect::<Vec<_>>();
1973+
let result = rotate_nested_vectors(a).collect::<Vec<_>>();
19851974

19861975
let expected = vec!["a1", "b1", "c1"];
19871976
assert_eq!(expected, result);
19881977

19891978
// test an empty vector at the end of the vectors
19901979
let a = vec![vec!["a0", "b0", "c0"], vec![]];
1991-
let result = zip_nested_vectors(a, TEST_RESULT_SIZE).collect::<Vec<_>>();
1980+
let result = rotate_nested_vectors(a).collect::<Vec<_>>();
19921981

19931982
let expected = vec!["a0", "b0", "c0"];
19941983
assert_eq!(expected, result);
@@ -2002,15 +1991,15 @@ mod test {
20021991
vec![],
20031992
];
20041993

2005-
let result = zip_nested_vectors(a, TEST_RESULT_SIZE).collect::<Vec<_>>();
1994+
let result = rotate_nested_vectors(a).collect::<Vec<_>>();
20061995

2007-
let expected = vec!["a1", "a3", "b1"];
1996+
let expected = vec!["a1", "a3", "b1", "b3", "c1"];
20081997
assert_eq!(expected, result);
20091998

20101999
// test one element in the first nested vectore and two elements in the second nested
20112000
// vector
20122001
let a = vec![vec!["a0"], vec!["a1", "b1"]];
2013-
let result = zip_nested_vectors(a, TEST_RESULT_SIZE).collect::<Vec<_>>();
2002+
let result = rotate_nested_vectors(a).collect::<Vec<_>>();
20142003

20152004
let expected = vec!["a0", "a1", "b1"];
20162005
assert_eq!(expected, result);

0 commit comments

Comments
 (0)