From 665a5448207f4ff66f0074a43c5ff47441fc9a5b Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Tue, 29 Aug 2023 10:14:04 +0200 Subject: [PATCH 1/8] Replace transmute with a pointer cast This is one of the recommended alternatives to transmute function. --- src/kv/value.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kv/value.rs b/src/kv/value.rs index d4c45ea7f..c93a300e5 100644 --- a/src/kv/value.rs +++ b/src/kv/value.rs @@ -470,14 +470,14 @@ impl<'v> From<&'v i128> for Value<'v> { impl<'v> From<&'v std::num::NonZeroU128> for Value<'v> { fn from(v: &'v std::num::NonZeroU128) -> Value<'v> { // SAFETY: `NonZeroU128` and `u128` have the same ABI - Value::from_value_bag(unsafe { std::mem::transmute::<&std::num::NonZeroU128, &u128>(v) }) + Value::from_value_bag(unsafe { &*(v as *const std::num::NonZeroU128 as *const u128) }) } } impl<'v> From<&'v std::num::NonZeroI128> for Value<'v> { fn from(v: &'v std::num::NonZeroI128) -> Value<'v> { // SAFETY: `NonZeroI128` and `i128` have the same ABI - Value::from_value_bag(unsafe { std::mem::transmute::<&std::num::NonZeroI128, &i128>(v) }) + Value::from_value_bag(unsafe { &*(v as *const std::num::NonZeroI128 as *const i128) }) } } From f100fb880a7971bae8ea4834653ef58077992317 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Tue, 29 Aug 2023 10:16:07 +0200 Subject: [PATCH 2/8] Implement ToValue for Arc --- src/kv/value.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/kv/value.rs b/src/kv/value.rs index c93a300e5..a744b605e 100644 --- a/src/kv/value.rs +++ b/src/kv/value.rs @@ -589,6 +589,7 @@ impl<'v> Value<'v> { #[cfg(feature = "kv_unstable_std")] mod std_support { use std::borrow::Cow; + use std::sync::Arc; use super::*; @@ -601,6 +602,15 @@ mod std_support { } } + impl ToValue for Arc + where + T: ToValue + ?Sized, + { + fn to_value(&self) -> Value { + (**self).to_value() + } + } + impl ToValue for String { fn to_value(&self) -> Value { Value::from(&**self) From de5711849bb4b0ed68943a4a4c0e9955a5cc16fb Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Tue, 29 Aug 2023 10:16:22 +0200 Subject: [PATCH 3/8] Implement ToValue for Rc --- src/kv/value.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/kv/value.rs b/src/kv/value.rs index a744b605e..352f965ea 100644 --- a/src/kv/value.rs +++ b/src/kv/value.rs @@ -589,6 +589,7 @@ impl<'v> Value<'v> { #[cfg(feature = "kv_unstable_std")] mod std_support { use std::borrow::Cow; + use std::rc::Rc; use std::sync::Arc; use super::*; @@ -611,6 +612,15 @@ mod std_support { } } + impl ToValue for Rc + where + T: ToValue + ?Sized, + { + fn to_value(&self) -> Value { + (**self).to_value() + } + } + impl ToValue for String { fn to_value(&self) -> Value { Value::from(&**self) From 0af453971ef8c72c0eed98421caa907f9ab33104 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Tue, 29 Aug 2023 10:24:49 +0200 Subject: [PATCH 4/8] Remove cfg(test) attribute from Source::{get,count} Test code can still overwrite the methods. --- src/kv/source.rs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/kv/source.rs b/src/kv/source.rs index 2a26c4a05..d4231b75e 100644 --- a/src/kv/source.rs +++ b/src/kv/source.rs @@ -30,14 +30,10 @@ pub trait Source { /// /// A source that can provide a more efficient implementation of this method /// should override it. - #[cfg(not(test))] fn get(&self, key: Key) -> Option> { get_default(self, key) } - #[cfg(test)] - fn get(&self, key: Key) -> Option>; - /// Count the number of key-value pairs that can be visited. /// /// # Implementation notes @@ -47,13 +43,9 @@ pub trait Source { /// /// A subsequent call to `visit` should yield the same number of key-value pairs /// to the visitor, unless that visitor fails part way through. - #[cfg(not(test))] fn count(&self) -> usize { count_default(self) } - - #[cfg(test)] - fn count(&self) -> usize; } /// The default implementation of `Source::get` @@ -714,14 +706,6 @@ mod tests { fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { visitor.visit_pair(self.key.to_key(), self.value.to_value()) } - - fn get(&self, key: Key) -> Option> { - get_default(self, key) - } - - fn count(&self) -> usize { - count_default(self) - } } assert_eq!(1, Source::count(&("a", 1))); From df6eadc2c7d130010c49c9347f81d9b37b8e0914 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Tue, 29 Aug 2023 10:34:21 +0200 Subject: [PATCH 5/8] Implement Source for Arc --- src/kv/source.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/kv/source.rs b/src/kv/source.rs index d4231b75e..736e072d8 100644 --- a/src/kv/source.rs +++ b/src/kv/source.rs @@ -225,6 +225,7 @@ mod std_support { use std::borrow::Borrow; use std::collections::{BTreeMap, HashMap}; use std::hash::{BuildHasher, Hash}; + use std::sync::Arc; impl Source for Box where @@ -243,6 +244,23 @@ mod std_support { } } + impl Source for Arc + where + S: Source + ?Sized, + { + fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { + Source::visit(&**self, visitor) + } + + fn get(&self, key: Key) -> Option> { + Source::get(&**self, key) + } + + fn count(&self) -> usize { + Source::count(&**self) + } + } + impl Source for Vec where S: Source, From 78cfeae8b5b63ba42f6286824b6c888ddb18e415 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Tue, 29 Aug 2023 10:35:04 +0200 Subject: [PATCH 6/8] Implement Source for Rc --- src/kv/source.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/kv/source.rs b/src/kv/source.rs index 736e072d8..38edf8865 100644 --- a/src/kv/source.rs +++ b/src/kv/source.rs @@ -225,6 +225,7 @@ mod std_support { use std::borrow::Borrow; use std::collections::{BTreeMap, HashMap}; use std::hash::{BuildHasher, Hash}; + use std::rc::Rc; use std::sync::Arc; impl Source for Box @@ -261,6 +262,23 @@ mod std_support { } } + impl Source for Rc + where + S: Source + ?Sized, + { + fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { + Source::visit(&**self, visitor) + } + + fn get(&self, key: Key) -> Option> { + Source::get(&**self, key) + } + + fn count(&self) -> usize { + Source::count(&**self) + } + } + impl Source for Vec where S: Source, From 154b58140a02e8d26b160339d7572cd492a2742c Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Tue, 29 Aug 2023 10:41:48 +0200 Subject: [PATCH 7/8] Small code simplification --- src/kv/source.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/kv/source.rs b/src/kv/source.rs index 38edf8865..8441e3d04 100644 --- a/src/kv/source.rs +++ b/src/kv/source.rs @@ -49,7 +49,7 @@ pub trait Source { } /// The default implementation of `Source::get` -pub(crate) fn get_default<'v>(source: &'v (impl Source + ?Sized), key: Key) -> Option> { +fn get_default<'v>(source: &'v (impl Source + ?Sized), key: Key) -> Option> { struct Get<'k, 'v> { key: Key<'k>, found: Option>, @@ -72,7 +72,7 @@ pub(crate) fn get_default<'v>(source: &'v (impl Source + ?Sized), key: Key) -> O } /// The default implementation of `Source::count`. -pub(crate) fn count_default(source: impl Source) -> usize { +fn count_default(source: impl Source) -> usize { struct Count(usize); impl<'kvs> Visitor<'kvs> for Count { @@ -159,7 +159,7 @@ where S: Source, { fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { - if let Some(ref source) = *self { + if let Some(source) = self { source.visit(visitor)?; } From 432f66d7172b37c26c08606ae57d185ff1833dda Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Tue, 29 Aug 2023 10:42:28 +0200 Subject: [PATCH 8/8] Fix Source::count for [S] The previous implementation didn't consider that the underlying Source implementation S can have more than one key-value pairs. --- src/kv/source.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kv/source.rs b/src/kv/source.rs index 8441e3d04..c8e7a05a3 100644 --- a/src/kv/source.rs +++ b/src/kv/source.rs @@ -150,7 +150,7 @@ where } fn count(&self) -> usize { - self.len() + self.iter().map(Source::count).sum() } }