From c7976ec44bdbd247061711d97a713f32b1e3a7f9 Mon Sep 17 00:00:00 2001 From: ghe0 Date: Fri, 23 Aug 2024 01:37:22 +0300 Subject: [PATCH] added paginated list of nodes --- src/persistence.rs | 85 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/src/persistence.rs b/src/persistence.rs index a667faa..6827c75 100644 --- a/src/persistence.rs +++ b/src/persistence.rs @@ -108,6 +108,31 @@ impl FileManager { file.read_exact(&mut node_bytes).await?; Ok(Node::from_bytes(node_bytes)) } + + /// Returns 20 nodes from the disk. + /// Specify offset (the number of nodes to skip). + async fn get_page_of_20(&self, offset: u64) -> std::io::Result> { + let mut file = self.file.lock().await; + file.seek(SeekFrom::Start( + offset + .wrapping_mul(DATA_SIZE.try_into().unwrap_or(0)), + )) + .await?; + let mut nodes = Vec::new(); + let mut count = 0; + loop { + let mut node_bytes = [0; DATA_SIZE]; + if let Err(_) = file.read_exact(&mut node_bytes).await { + break; + }; + nodes.push(Node::from_bytes(node_bytes)); + count += 1; + if count == 20 { + break; + } + } + Ok(nodes) + } } #[cfg(test)] @@ -287,4 +312,64 @@ mod tests { remove_file(get_test_file_name(function_name)).await?; Ok(()) } + + #[tokio::test] + async fn get_page_of_20_nodes() -> Result<()> { + let function_name = "get_page_of_20_nodes"; + let manager = setup_test_file(function_name).await?; + let mut count = 0; + let mut nodes: Vec = Vec::new(); + while count < 100 { + let node = get_random_node(); + if count >= 23 && count < 43 { + nodes.push(node.clone()); + } + manager.append_node(node).await?; + count += 1; + } + count = 23; + let mut r_nodes = manager.get_page_of_20(23).await?.into_iter(); + for node in nodes.iter() { + let r_node = r_nodes.next().unwrap(); + println!("{} {} {}", count, node.ip_as_string(), r_node.ip_as_string()); + assert_eq!(node.ip_as_string(), r_node.ip_as_string()); + assert_eq!(node.keypair, r_node.keypair); + count += 1; + if count == 44 { + break; + } + } + remove_file(get_test_file_name(function_name)).await?; + Ok(()) + } + + #[tokio::test] + async fn get_last_page() -> Result<()> { + let function_name = "get_last_page"; + let manager = setup_test_file(function_name).await?; + let mut count = 0; + let mut nodes: Vec = Vec::new(); + while count < 97 { + let node = get_random_node(); + if count >= 90 { + nodes.push(node.clone()); + } + manager.append_node(node).await?; + count += 1; + } + count = 23; + let mut r_nodes = manager.get_page_of_20(90).await?.into_iter(); + for node in nodes.iter() { + let r_node = r_nodes.next().unwrap(); + println!("{} {} {}", count, node.ip_as_string(), r_node.ip_as_string()); + assert_eq!(node.ip_as_string(), r_node.ip_as_string()); + assert_eq!(node.keypair, r_node.keypair); + count += 1; + if count == 44 { + break; + } + } + remove_file(get_test_file_name(function_name)).await?; + Ok(()) + } }