tree_overlay.rs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2026-2026 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. //! Simulate the creation of two [`TreeOverlay`] on top of two [`Tree`]
  19. //! instances, and perform writes to verify overlay's cache
  20. //! functionality.
  21. use kvdb_overlay::{Database, Result, TreeOverlay};
  22. const TREE_1: &str = "_tree1";
  23. const TREE_2: &str = "_tree2";
  24. #[test]
  25. fn tree_overlay() -> Result<()> {
  26. // Initialize database
  27. let (db, _folder) = Database::open_temp()?;
  28. // Initialize trees and their overlays
  29. let tree_1 = db.open_tree_default(TREE_1)?;
  30. let tree_2 = db.open_tree_default(TREE_2)?;
  31. let mut overlay_1 = TreeOverlay::new(&tree_1);
  32. let mut overlay_2 = TreeOverlay::new(&tree_2);
  33. // Check overlays are empty
  34. assert!(overlay_1.is_empty()?);
  35. assert!(overlay_2.is_empty()?);
  36. // Check last value is `None`
  37. assert_eq!(overlay_1.last()?, None);
  38. assert_eq!(overlay_1.last()?, None);
  39. // Insert some values to the overlays
  40. overlay_1.insert(b"key_a", b"val_a")?;
  41. overlay_1.insert(b"key_b", b"val_b")?;
  42. overlay_1.insert(b"key_c", b"val_c")?;
  43. overlay_2.insert(b"key_d", b"val_d")?;
  44. overlay_2.insert(b"key_e", b"val_e")?;
  45. overlay_2.insert(b"key_f", b"val_f")?;
  46. // Verify they are in the overlays
  47. assert_eq!(overlay_1.get(b"key_a")?, Some(b"val_a".into()));
  48. assert_eq!(overlay_1.get(b"key_b")?, Some(b"val_b".into()));
  49. assert_eq!(overlay_1.get(b"key_c")?, Some(b"val_c".into()));
  50. assert_eq!(overlay_2.get(b"key_d")?, Some(b"val_d".into()));
  51. assert_eq!(overlay_2.get(b"key_e")?, Some(b"val_e".into()));
  52. assert_eq!(overlay_2.get(b"key_f")?, Some(b"val_f".into()));
  53. // Check overlays are not empty
  54. assert!(!overlay_1.is_empty()?);
  55. assert!(!overlay_2.is_empty()?);
  56. // Check their last values
  57. assert_eq!(overlay_1.last()?, Some((b"key_c".into(), b"val_c".into())));
  58. assert_eq!(overlay_2.last()?, Some((b"key_f".into(), b"val_f".into())));
  59. // Verify they are not in the database
  60. assert_eq!(tree_1.get(b"key_a")?, None);
  61. assert_eq!(tree_1.get(b"key_b")?, None);
  62. assert_eq!(tree_1.get(b"key_c")?, None);
  63. assert_eq!(tree_2.get(b"key_d")?, None);
  64. assert_eq!(tree_2.get(b"key_e")?, None);
  65. assert_eq!(tree_2.get(b"key_f")?, None);
  66. // Now we write all changes to the database
  67. db.write_tree_overlays_changes(&[&overlay_1, &overlay_2])?;
  68. db.flush_default_mode()?;
  69. // Verify database contains keys
  70. assert_eq!(tree_1.get(b"key_a")?, Some(b"val_a".into()));
  71. assert_eq!(tree_1.get(b"key_b")?, Some(b"val_b".into()));
  72. assert_eq!(tree_1.get(b"key_c")?, Some(b"val_c".into()));
  73. assert_eq!(tree_2.get(b"key_d")?, Some(b"val_d".into()));
  74. assert_eq!(tree_2.get(b"key_e")?, Some(b"val_e".into()));
  75. assert_eq!(tree_2.get(b"key_f")?, Some(b"val_f".into()));
  76. Ok(())
  77. }
  78. #[test]
  79. fn tree_overlay_last() -> Result<()> {
  80. // Initialize database
  81. let (db, _folder) = Database::open_temp()?;
  82. // Initialize tree and its overlay
  83. let tree = db.open_tree_default(TREE_1)?;
  84. let mut overlay = TreeOverlay::new(&tree);
  85. assert!(overlay.is_empty()?);
  86. // Check last is None
  87. assert_eq!(overlay.last()?, None);
  88. // Insert a value to the tree
  89. tree.insert(b"key_a", b"val_a")?;
  90. // Check last is the last tree key
  91. let last = overlay.last()?.unwrap();
  92. assert_eq!(last.0, b"key_a");
  93. assert_eq!(last.1, b"val_a");
  94. // Remove the key from the overlay and check
  95. // last is None
  96. overlay.remove(b"key_a")?;
  97. assert_eq!(overlay.last()?, None);
  98. // Remove value from the tree
  99. tree.remove(b"key_a")?;
  100. // Insert key in overlay and check its last
  101. overlay.insert(b"key_a", b"val_a")?;
  102. assert!(tree.is_empty()?);
  103. let last = overlay.last()?.unwrap();
  104. assert_eq!(last.0, b"key_a");
  105. assert_eq!(last.1, b"val_a");
  106. // Insert a key in the tree that is supposed to be last
  107. tree.insert(b"key_b", b"val_b")?;
  108. let last = overlay.last()?.unwrap();
  109. assert_eq!(last.0, b"key_b");
  110. assert_eq!(last.1, b"val_b");
  111. // Remove the key from the overlay and check
  112. // last is the correct one
  113. overlay.remove(b"key_b")?;
  114. let last = overlay.last()?.unwrap();
  115. assert_eq!(last.0, b"key_a");
  116. assert_eq!(last.1, b"val_a");
  117. // Reset the state
  118. tree.remove(b"key_b")?;
  119. tree.insert(b"key_a", b"val_a")?;
  120. tree.insert(b"key_c", b"val_c")?;
  121. tree.insert(b"key_d", b"val_d")?;
  122. let mut overlay = TreeOverlay::new(&tree);
  123. overlay.insert(b"key_b", b"val_b")?;
  124. overlay.remove(b"key_d")?;
  125. // Check last is the correct one
  126. let last = overlay.last()?.unwrap();
  127. assert_eq!(last.0, b"key_c");
  128. assert_eq!(last.1, b"val_c");
  129. Ok(())
  130. }
  131. #[test]
  132. fn tree_overlay_iteration() -> Result<()> {
  133. // Initialize database
  134. let (db, _folder) = Database::open_temp()?;
  135. // Initialize tree and its overlay
  136. let tree = db.open_tree_default(TREE_1)?;
  137. tree.insert(b"key_a", b"val_a")?;
  138. tree.insert(b"key_c", b"val_c")?;
  139. tree.insert(b"key_e", b"val_e")?;
  140. let mut overlay = TreeOverlay::new(&tree);
  141. // Insert some values to the overlay
  142. overlay.insert(b"key_b", b"val_b")?;
  143. overlay.insert(b"key_d", b"val_d")?;
  144. overlay.insert(b"key_e", b"val_ee")?;
  145. overlay.insert(b"key_f", b"val_f")?;
  146. // Remove some values from the overlay
  147. overlay.remove(b"key_c")?;
  148. overlay.remove(b"key_d")?;
  149. // Iterate overlay to verify sequence
  150. let expected_sequence = [
  151. (b"key_a".to_vec(), b"val_a".to_vec()),
  152. (b"key_b".to_vec(), b"val_b".to_vec()),
  153. (b"key_e".to_vec(), b"val_ee".to_vec()),
  154. (b"key_f".to_vec(), b"val_f".to_vec()),
  155. ];
  156. for (index, record) in overlay.iter().enumerate() {
  157. assert_eq!(record?, expected_sequence[index]);
  158. }
  159. // We can even iterate without calling .iter()
  160. let mut index = 0;
  161. #[allow(clippy::explicit_counter_loop)]
  162. for record in &overlay {
  163. assert_eq!(record?, expected_sequence[index]);
  164. index += 1;
  165. }
  166. Ok(())
  167. }