value.rs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  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. use std::io::{Cursor, Read};
  19. use kvdb_overlay::{Database, DatabaseOverlay, Error, Result, TreeOverlay, Value};
  20. #[test]
  21. fn tree_value_owns_bytes() -> Result<()> {
  22. let (db, _folder) = Database::open_temp()?;
  23. let value = {
  24. let tree = db.open_tree_default("values")?;
  25. assert!(tree.get(b"missing")?.is_none());
  26. tree.insert(b"empty", b"")?;
  27. assert_eq!(tree.get(b"empty")?.unwrap().as_ref(), b"");
  28. tree.insert(b"key", &[42; 128])?;
  29. let value = tree.get(b"key")?.unwrap();
  30. assert!(matches!(value, Value::Backend(_)));
  31. tree.insert(b"key", b"replacement")?;
  32. tree.remove(b"key")?;
  33. value
  34. };
  35. drop(db);
  36. let mut reader = Cursor::new(value);
  37. let mut bytes = [0; 128];
  38. reader.read_exact(&mut bytes)?;
  39. assert_eq!(bytes, [42; 128]);
  40. assert_eq!(reader.read(&mut bytes)?, 0);
  41. Ok(())
  42. }
  43. #[test]
  44. fn overlay_value_borrows_cache() -> Result<()> {
  45. let (db, _folder) = Database::open_temp()?;
  46. let tree = db.open_tree_default("values")?;
  47. tree.insert(b"key", b"backend")?;
  48. let mut overlay = TreeOverlay::new(&tree);
  49. assert!(overlay.get(b"missing")?.is_none());
  50. let value = overlay.get(b"key")?.unwrap();
  51. assert!(matches!(value, Value::Backend(_)));
  52. assert_eq!(value.as_ref(), b"backend");
  53. overlay.insert(b"key", &[7; 128])?;
  54. let value = overlay.get(b"key")?.unwrap();
  55. assert!(matches!(value, Value::Cached(_)));
  56. assert_eq!(
  57. value.as_ref().as_ptr(),
  58. overlay.state.cache.get(b"key".as_slice()).unwrap().as_ptr()
  59. );
  60. let mut reader = value.as_ref();
  61. let mut bytes = [0; 128];
  62. reader.read_exact(&mut bytes)?;
  63. assert_eq!(bytes, [7; 128]);
  64. assert_eq!(reader.read(&mut bytes)?, 0);
  65. overlay.remove(b"key")?;
  66. assert!(overlay.get(b"key")?.is_none());
  67. assert!(tree.get(b"key")?.is_some());
  68. overlay.insert(b"key", b"")?;
  69. assert_eq!(overlay.get(b"key")?.unwrap().as_ref(), b"");
  70. // Removals take precedence even if a public cache state contains both.
  71. overlay.state.removed.insert(b"key".to_vec());
  72. assert!(overlay.get(b"key")?.is_none());
  73. Ok(())
  74. }
  75. #[test]
  76. fn database_overlay_value() -> Result<()> {
  77. let (db, _folder) = Database::open_temp()?;
  78. let tree = db.open_tree_default("values")?;
  79. tree.insert(b"key", b"backend")?;
  80. let mut overlay = DatabaseOverlay::new(&db, vec![])?;
  81. assert!(matches!(
  82. overlay.get("values", b"key"),
  83. Err(Error::CollectionNotFound(_))
  84. ));
  85. overlay.open_tree_default("values", false)?;
  86. assert!(overlay.get("values", b"missing")?.is_none());
  87. assert_eq!(overlay.get("values", b"key")?.unwrap().as_ref(), b"backend");
  88. overlay.insert("values", b"key", b"cached")?;
  89. assert_eq!(overlay.get("values", b"key")?.unwrap().as_ref(), b"cached");
  90. overlay.remove("values", b"key")?;
  91. assert!(overlay.get("values", b"key")?.is_none());
  92. overlay.drop_tree("values")?;
  93. assert!(matches!(
  94. overlay.get("values", b"key"),
  95. Err(Error::CollectionNotFound(_))
  96. ));
  97. Ok(())
  98. }
  99. #[test]
  100. fn value_into_vec_copies_bytes() -> Result<()> {
  101. for cached in [false, true] {
  102. for original in [b"value".as_slice(), b""] {
  103. let mut bytes = {
  104. let (db, _folder) = Database::open_temp()?;
  105. let tree = db.open_tree_default("values")?;
  106. tree.insert(b"key", original)?;
  107. let mut overlay = TreeOverlay::new(&tree);
  108. if cached {
  109. overlay.insert(b"key", original)?;
  110. }
  111. let value = overlay.get(b"key")?.unwrap();
  112. if cached {
  113. assert!(matches!(value, Value::Cached(_)));
  114. } else {
  115. assert!(matches!(value, Value::Backend(_)));
  116. }
  117. let mut bytes = value.into_vec();
  118. assert_eq!(bytes, original);
  119. bytes.reverse();
  120. bytes.push(b'!');
  121. assert_eq!(overlay.get(b"key")?.unwrap().as_ref(), original);
  122. assert_eq!(tree.get(b"key")?.unwrap().as_ref(), original);
  123. overlay.insert(b"key", b"replacement")?;
  124. overlay.remove(b"key")?;
  125. bytes
  126. };
  127. assert_eq!(bytes.pop(), Some(b'!'));
  128. bytes.reverse();
  129. assert_eq!(bytes, original);
  130. }
  131. }
  132. Ok(())
  133. }