Skip to content

Commit

Permalink
Merge branch 'main' into tagging2
Browse files Browse the repository at this point in the history
  • Loading branch information
milyin committed Feb 8, 2024
2 parents 64af0b7 + 2bd4518 commit 4808816
Show file tree
Hide file tree
Showing 17 changed files with 1,031 additions and 163 deletions.
13 changes: 12 additions & 1 deletion .config/nextest.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
# By default, retry a few times until pass the test within the specified timeout
[profile.default]
retries = 4
slow-timeout = { period = "60s", terminate-after = 2 }

# Run the following tests exclusively with longer timeout
[[profile.default.overrides]]
filter = 'test(/zenoh_session_unicast/)'
filter = """
test(=zenoh_session_unicast) |
test(=zenoh_session_multicast) |
test(=three_node_combination)
"""
threads-required = 'num-cpus'
slow-timeout = { period = "60s", terminate-after = 6 }
26 changes: 24 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ description = "Zenoh: Zero Overhead Pub/sub, Store/Query and Compute."
# (https://github.com/rust-lang/cargo/issues/11329)
[workspace.dependencies]
aes = "0.8.2"
ahash = "0.8.7"
anyhow = { version = "1.0.69", default-features = false } # Default features are disabled due to usage in no_std crates
async-executor = "1.5.0"
async-global-executor = "2.3.1"
Expand Down
6 changes: 3 additions & 3 deletions DEFAULT_CONFIG.json5
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,10 @@
/// The initial exponential backoff time in nanoseconds to allow the batching to eventually progress.
/// Higher values lead to a more aggressive batching but it will introduce additional latency.
backoff: 100,
// Number of threads dedicated to transmission
// By default, the number of threads is calculated as follows: 1 + ((#cores - 1) / 4)
// threads: 4,
},
// Number of threads dedicated to transmission
// By default, the number of threads is calculated as follows: 1 + ((#cores - 1) / 4)
// threads: 4,
},
/// Configure the zenoh RX parameters of a link
rx: {
Expand Down
1 change: 1 addition & 0 deletions commons/zenoh-keyexpr/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ hashbrown = { workspace = true }

# NOTE: May cause problems when testing no_std stuff. Check this tool: https://docs.rs/crate/cargo-no-dev-deps/0.1.0
[dev-dependencies]
ahash = { workspace = true }
criterion = { workspace = true }
lazy_static = { workspace = true }
rand = { workspace = true, features = ["default"] }
Expand Down
20 changes: 17 additions & 3 deletions commons/zenoh-keyexpr/benches/keyexpr_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@ fn main() {
let mut intersections = Averager::default();
let results = Benchmarker::benchmark(|b| {
let keys = KeySet::generate(total, wildness, no_double_stars);
let mut ketree: KeBoxTree<_> = KeBoxTree::new();
let mut vectree: KeBoxTree<_, bool, VecSetProvider> = KeBoxTree::new();
let mut hashtree: KeBoxTree<_, bool, HashMapProvider> = KeBoxTree::new();
let mut ketree = KeBoxTree::new();
let mut vectree: KeBoxTree<_, bool, VecSetProvider> = KeBoxTree::default();
let mut hashtree: KeBoxTree<_, bool, HashMapProvider> = KeBoxTree::default();
let mut ahashtree: KeBoxTree<_, bool, HashMapProvider<ahash::AHasher>> =
KeBoxTree::default();
let (kearctree, mut token): (KeArcTree<i32>, _) = KeArcTree::new().unwrap();
let mut map = HashMap::new();
for key in keys.iter() {
Expand All @@ -58,13 +60,15 @@ fn main() {
});
b.run_once("vectree_insert", || vectree.insert(key, 0));
b.run_once("hashtree_insert", || hashtree.insert(key, 0));
b.run_once("ahashtree_insert", || ahashtree.insert(key, 0));
b.run_once("hashmap_insert", || map.insert(key.to_owned(), 0));
}
for key in keys.iter() {
b.run_once("ketree_fetch", || ketree.node(key));
b.run_once("kearctree_fetch", || kearctree.node(&token, key));
b.run_once("vectree_fetch", || vectree.node(key));
b.run_once("hashtree_fetch", || hashtree.node(key));
b.run_once("ahashtree_fetch", || ahashtree.node(key));
b.run_once("hashmap_fetch", || map.get(key));
}
for key in keys.iter() {
Expand All @@ -81,6 +85,9 @@ fn main() {
b.run_once("hashtree_intersect", || {
hashtree.intersecting_nodes(key).count()
});
b.run_once("ahashtree_intersect", || {
ahashtree.intersecting_nodes(key).count()
});
b.run_once("hashmap_intersect", || {
map.iter().filter(|(k, _)| key.intersects(k)).count()
});
Expand All @@ -92,6 +99,9 @@ fn main() {
});
b.run_once("vectree_include", || vectree.included_nodes(key).count());
b.run_once("hashtree_include", || hashtree.included_nodes(key).count());
b.run_once("ahashtree_include", || {
ahashtree.included_nodes(key).count()
});
b.run_once("hashmap_include", || {
map.iter().filter(|(k, _)| key.includes(k)).count()
});
Expand All @@ -102,21 +112,25 @@ fn main() {
"kearctree_insert",
"vectree_insert",
"hashtree_insert",
"ahashtree_insert",
"hashmap_insert",
"ketree_fetch",
"kearctree_fetch",
"vectree_fetch",
"hashtree_fetch",
"ahashtree_fetch",
"hashmap_fetch",
"ketree_intersect",
"kearctree_intersect",
"vectree_intersect",
"hashtree_intersect",
"ahashtree_intersect",
"hashmap_intersect",
"ketree_include",
"kearctree_include",
"vectree_include",
"hashtree_include",
"ahashtree_include",
"hashmap_include",
] {
let b = results.benches.get(name).unwrap();
Expand Down
5 changes: 4 additions & 1 deletion commons/zenoh-keyexpr/src/key_expr/fuzzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ use super::OwnedKeyExpr;

fn random_chunk(rng: &'_ mut impl rand::Rng) -> impl Iterator<Item = u8> + '_ {
let n = rng.gen_range(1..3);
(0..n).map(move |_| rng.sample(rand::distributions::Uniform::from(b'a'..b'c')))
rng.gen_bool(0.05)
.then_some(b'@')
.into_iter()
.chain((0..n).map(move |_| rng.sample(rand::distributions::Uniform::from(b'a'..b'c'))))
}

fn make(ke: &mut Vec<u8>, rng: &mut impl rand::Rng) {
Expand Down
62 changes: 61 additions & 1 deletion commons/zenoh-keyexpr/src/keyexpr_tree/arc_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ fn ketree_borrow_mut<'a, T, Token: TokenTrait>(
/// A shared KeTree.
///
/// The tree and its nodes have shared ownership, while their mutability is managed through the `Token`.
/// The `(node, &token)` tuple implements [`core::ops::Deref`], while `(node, &mut token)` implements [`core::ops::DerefMut`].
///
/// Most of its methods are declared in the [`ITokenKeyExprTree`] trait.
pub struct KeArcTree<
Weight,
Token: TokenTrait = DefaultToken,
Expand All @@ -82,6 +83,14 @@ impl<
> KeArcTree<Weight, DefaultToken, Wildness, Children>
{
/// Constructs the KeArcTree, returning it and its token, unless constructing the Token failed.
///
/// # Type inference papercut
/// Despite some of `KeArcTree`'s generic parameters having default values, those are only taken into
/// account by the compiler when a type is named with some parameters omitted, and not when a type is
/// infered with the same parameters unconstrained.
///
/// The simplest way to resolve this is to eventually assign to tree part of the return value
/// to a variable or field whose type is named `KeArcTree<_>` (the `Weight` parameter can generally be infered).
pub fn new() -> Result<(Self, DefaultToken), <DefaultToken as TokenTrait>::ConstructionError> {
let token = DefaultToken::new()?;
Ok((Self::with_token(&token), token))
Expand Down Expand Up @@ -329,6 +338,57 @@ where
IterOrOption::Opt(self.node_mut(token, key).map(Into::into))
}
}

type IncluderItem = Self::Node;
type Includer = IterOrOption<
TokenPacker<
Includer<
'a,
Children,
Arc<TokenCell<KeArcTreeNode<Weight, Weak<()>, Wildness, Children, Token>, Token>>,
Weight,
>,
&'a Token,
>,
Self::IncluderItem,
>;
fn nodes_including(&'a self, token: &'a Token, key: &'a keyexpr) -> Self::Includer {
let inner = ketree_borrow(&self.inner, token);
if inner.wildness.get() || key.is_wild() {
IterOrOption::Iter(TokenPacker {
iter: Includer::new(&inner.children, key),
token,
})
} else {
IterOrOption::Opt(self.node(token, key))
}
}
type IncluderItemMut = Self::TreeIterItemMut;
type IncluderMut = IterOrOption<
TokenPacker<
Includer<
'a,
Children,
Arc<TokenCell<KeArcTreeNode<Weight, Weak<()>, Wildness, Children, Token>, Token>>,
Weight,
>,
&'a mut Token,
>,
Self::IncluderItemMut,
>;
fn nodes_including_mut(&'a self, token: &'a mut Token, key: &'a keyexpr) -> Self::IncluderMut {
let inner = ketree_borrow(&self.inner, token);
if inner.wildness.get() || key.is_wild() {
unsafe {
IterOrOption::Iter(TokenPacker {
iter: Includer::new(core::mem::transmute(&inner.children), key),
token,
})
}
} else {
IterOrOption::Opt(self.node_mut(token, key).map(Into::into))
}
}
type PruneNode = KeArcTreeNode<Weight, Weak<()>, Wildness, Children, Token>;

fn prune_where<F: FnMut(&mut Self::PruneNode) -> bool>(
Expand Down
48 changes: 38 additions & 10 deletions commons/zenoh-keyexpr/src/keyexpr_tree/box_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ use super::impls::KeyedSetProvider;
use super::support::IterOrOption;

/// A fully owned KeTree.
///
/// Note that most of `KeBoxTree`'s methods are declared in the [`IKeyExprTree`] and [`IKeyExprTreeMut`] traits.
#[repr(C)]
pub struct KeBoxTree<
Weight,
Expand All @@ -37,17 +39,13 @@ pub struct KeBoxTree<
wildness: Wildness,
}

impl<
Weight,
Wildness: IWildness,
Children: IChildrenProvider<Box<KeyExprTreeNode<Weight, Wildness, Children>>>,
> KeBoxTree<Weight, Wildness, Children>
impl<Weight> KeBoxTree<Weight, bool, DefaultChildrenProvider>
where
DefaultChildrenProvider:
IChildrenProvider<Box<KeyExprTreeNode<Weight, bool, DefaultChildrenProvider>>>,
{
pub fn new() -> Self {
KeBoxTree {
children: Default::default(),
wildness: Wildness::non_wild(),
}
Default::default()
}
}
impl<
Expand All @@ -57,7 +55,10 @@ impl<
> Default for KeBoxTree<Weight, Wildness, Children>
{
fn default() -> Self {
Self::new()
KeBoxTree {
children: Default::default(),
wildness: Wildness::non_wild(),
}
}
}

Expand Down Expand Up @@ -117,6 +118,20 @@ where
IterOrOption::Opt(node)
}
}

type IncluderItem = <Self::Includer as Iterator>::Item;
type Includer = IterOrOption<
Includer<'a, Children, Box<KeyExprTreeNode<Weight, Wildness, Children>>, Weight>,
&'a Self::Node,
>;
fn nodes_including(&'a self, ke: &'a keyexpr) -> Self::Includer {
if self.wildness.get() || ke.is_wild() {
Includer::new(&self.children, ke).into()
} else {
let node = self.node(ke);
IterOrOption::Opt(node)
}
}
}
impl<
'a,
Expand Down Expand Up @@ -218,6 +233,19 @@ where
IterOrOption::Opt(node)
}
}
type IncluderItemMut = <Self::IncluderMut as Iterator>::Item;
type IncluderMut = IterOrOption<
IncluderMut<'a, Children, Box<KeyExprTreeNode<Weight, Wildness, Children>>, Weight>,
&'a mut Self::Node,
>;
fn nodes_including_mut(&'a mut self, ke: &'a keyexpr) -> Self::IncluderMut {
if self.wildness.get() || ke.is_wild() {
IncluderMut::new(&mut self.children, ke).into()
} else {
let node = self.node_mut(ke);
IterOrOption::Opt(node)
}
}

fn prune_where<F: FnMut(&mut Self::Node) -> bool>(&mut self, mut predicate: F) {
let mut wild = false;
Expand Down
Loading

0 comments on commit 4808816

Please sign in to comment.