Skip to content

Commit 997c2fe

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 b4ac4a5 commit 997c2fe

File tree

1 file changed

+27
-34
lines changed

1 file changed

+27
-34
lines changed

lightning-invoice/src/utils.rs

Lines changed: 27 additions & 34 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,26 +270,20 @@ 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-
if total_hints_returned == result_size || hint_index == max_vector_length {
286+
if hint_index == max_vector_length {
291287
return None;
292288
};
293289
let hint_value = if vecs[vector_index].len() != 0 && vecs[vector_index].len() > hint_index {
@@ -301,7 +297,6 @@ fn zip_nested_vectors<T: Clone>(vecs: Vec<Vec<T>>, result_size: usize) -> impl I
301297
hint_index += 1;
302298
};
303299
if !hint_value.is_none() {
304-
total_hints_returned += 1;
305300
return hint_value;
306301
};
307302
})
@@ -792,7 +787,7 @@ mod test {
792787
use lightning::routing::router::{PaymentParameters, RouteParameters};
793788
use lightning::util::test_utils;
794789
use lightning::util::config::UserConfig;
795-
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};
796791
use std::collections::HashSet;
797792

798793
#[test]
@@ -1905,60 +1900,58 @@ mod test {
19051900

19061901
#[test]
19071902
fn test_zip_nested_vectors() {
1908-
const TEST_RESULT_SIZE: usize = 3;
1909-
19101903
// two nested vectors
19111904
let a = vec![vec!["a0", "b0", "c0"], vec!["a1", "b1"]];
1912-
let result = zip_nested_vectors(a, TEST_RESULT_SIZE).collect::<Vec<_>>();
1905+
let result = rotate_nested_vectors(a).collect::<Vec<_>>();
19131906

1914-
let expected = vec!["a0", "a1", "b0"];
1907+
let expected = vec!["a0", "a1", "b0", "b1", "c0"];
19151908
assert_eq!(expected, result);
19161909

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

19211914
let expected = vec!["a0", "b0", "c0"];
19221915
assert_eq!(expected, result);
19231916

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

1928-
let expected = vec!["a0", "a1", "b0"];
1921+
let expected = vec!["a0", "a1", "b0", "c0"];
19291922
assert_eq!(expected, result);
19301923

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

1935-
let expected = vec!["a0", "a1", "a2"];
1928+
let expected = vec!["a0", "a1", "a2", "b1", "c1"];
19361929
assert_eq!(expected, result);
19371930

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

19421935
let expected = vec!["a0"];
19431936
assert_eq!(expected, result);
19441937

19451938
// test single empty nested vector
19461939
let a:Vec<Vec<&str>> = vec![vec![]];
1947-
let result = zip_nested_vectors(a, TEST_RESULT_SIZE).collect::<Vec<_>>();
1940+
let result = rotate_nested_vectors(a).collect::<Vec<_>>();
19481941
let expected:Vec<&str> = vec![];
19491942

19501943
assert_eq!(expected, result);
19511944

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

19561949
let expected = vec!["a1", "b1", "c1"];
19571950
assert_eq!(expected, result);
19581951

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

19631956
let expected:Vec<&str> = vec![];
19641957
assert_eq!(expected, result);
@@ -1970,21 +1963,21 @@ mod test {
19701963
vec!["a1", "b1", "c1"],
19711964
vec!["a2", "b2", "c2"],
19721965
];
1973-
let result = zip_nested_vectors(a, TEST_RESULT_SIZE).collect::<Vec<_>>();
1966+
let result = rotate_nested_vectors(a).collect::<Vec<_>>();
19741967

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

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

19821975
let expected = vec!["a1", "b1", "c1"];
19831976
assert_eq!(expected, result);
19841977

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

19891982
let expected = vec!["a0", "b0", "c0"];
19901983
assert_eq!(expected, result);
@@ -1998,15 +1991,15 @@ mod test {
19981991
vec![],
19991992
];
20001993

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

2003-
let expected = vec!["a1", "a3", "b1"];
1996+
let expected = vec!["a1", "a3", "b1", "b3", "c1"];
20041997
assert_eq!(expected, result);
20051998

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

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

0 commit comments

Comments
 (0)