Skip to main content

zenoh_keyexpr/keyexpr_tree/impls/
hashmap_impl.rs

1//
2// Copyright (c) 2023 ZettaScale Technology
3//
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7// which is available at https://www.apache.org/licenses/LICENSE-2.0.
8//
9// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10//
11// Contributors:
12//   ZettaScale Zenoh Team, <zenoh@zettascale.tech>
13//
14
15use core::hash::Hasher;
16#[cfg(not(feature = "std"))]
17// `SipHasher` is deprecated in favour of a symbol that only exists in `std`
18#[allow(deprecated)]
19use core::hash::SipHasher as DefaultHasher;
20#[cfg(feature = "std")]
21use std::collections::{
22    hash_map::{DefaultHasher, Entry, Iter, IterMut, Values, ValuesMut},
23    HashMap,
24};
25
26#[cfg(not(feature = "std"))]
27use hashbrown::{
28    hash_map::{Entry, Iter, IterMut, Values, ValuesMut},
29    HashMap,
30};
31
32use crate::keyexpr_tree::*;
33
34#[cfg_attr(not(feature = "std"), allow(deprecated))]
35pub struct HashMapProvider<Hash: Hasher + Default + 'static = DefaultHasher>(
36    core::marker::PhantomData<Hash>,
37);
38impl<T: 'static, Hash: Hasher + Default + 'static> IChildrenProvider<T> for HashMapProvider<Hash> {
39    type Assoc = HashMap<OwnedKeyExpr, T, core::hash::BuildHasherDefault<Hash>>;
40}
41
42#[cfg(not(feature = "std"))]
43impl<'a: 'b, 'b, T: HasChunk, S: core::hash::BuildHasher> IEntry<'a, 'b, T>
44    for Entry<'a, OwnedKeyExpr, T, S>
45{
46    fn get_or_insert_with<F: FnOnce(&'b keyexpr) -> T>(self, f: F) -> &'a mut T {
47        match self {
48            Entry::Vacant(entry) => {
49                // SAFETY: upheld by the surrounding invariants and prior validation.
50                let value = unsafe { f(core::mem::transmute::<&keyexpr, &keyexpr>(entry.key())) };
51                entry.insert(value)
52            }
53            Entry::Occupied(v) => v.into_mut(),
54        }
55    }
56}
57#[cfg(feature = "std")]
58impl<'a: 'b, 'b, T: HasChunk> IEntry<'a, 'b, T> for Entry<'a, OwnedKeyExpr, T> {
59    fn get_or_insert_with<F: FnOnce(&'b keyexpr) -> T>(self, f: F) -> &'a mut T {
60        match self {
61            Entry::Vacant(entry) => {
62                // SAFETY: upheld by the surrounding invariants and prior validation.
63                let value = unsafe { f(core::mem::transmute::<&keyexpr, &keyexpr>(entry.key())) };
64                entry.insert(value)
65            }
66            Entry::Occupied(v) => v.into_mut(),
67        }
68    }
69}
70
71impl<T: HasChunk + AsNode<T> + AsNodeMut<T> + 'static, S: core::hash::BuildHasher> IChildren<T>
72    for HashMap<OwnedKeyExpr, T, S>
73{
74    type Node = T;
75    fn child_at(&self, chunk: &keyexpr) -> Option<&T> {
76        self.get(chunk)
77    }
78    fn child_at_mut(&mut self, chunk: &keyexpr) -> Option<&mut T> {
79        self.get_mut(chunk)
80    }
81    fn remove(&mut self, chunk: &keyexpr) -> Option<Self::Node> {
82        self.remove(chunk)
83    }
84    fn len(&self) -> usize {
85        self.len()
86    }
87    fn is_empty(&self) -> bool {
88        self.is_empty()
89    }
90
91    #[cfg(feature = "std")]
92    type Entry<'a, 'b>
93        = Entry<'a, OwnedKeyExpr, T>
94    where
95        Self: 'a,
96        'a: 'b,
97        T: 'b;
98    #[cfg(not(feature = "std"))]
99    type Entry<'a, 'b>
100        = Entry<'a, OwnedKeyExpr, T, S>
101    where
102        Self: 'a,
103        'a: 'b,
104        T: 'b;
105    fn entry<'a, 'b>(&'a mut self, chunk: &'b keyexpr) -> Self::Entry<'a, 'b>
106    where
107        Self: 'a,
108        'a: 'b,
109        T: 'b,
110    {
111        self.entry(chunk.into())
112    }
113
114    type Iter<'a>
115        = Values<'a, OwnedKeyExpr, T>
116    where
117        Self: 'a;
118    fn children<'a>(&'a self) -> Self::Iter<'a>
119    where
120        Self: 'a,
121    {
122        self.values()
123    }
124
125    type IterMut<'a>
126        = ValuesMut<'a, OwnedKeyExpr, T>
127    where
128        Self: 'a;
129
130    fn children_mut<'a>(&'a mut self) -> Self::IterMut<'a>
131    where
132        Self: 'a,
133    {
134        self.values_mut()
135    }
136
137    fn filter_out<F: FnMut(&mut T) -> bool>(&mut self, predicate: &mut F) {
138        self.retain(|_, v| predicate(v));
139    }
140
141    type Intersection<'a>
142        = super::FilterMap<Iter<'a, OwnedKeyExpr, T>, super::Intersection<'a>>
143    where
144        Self: 'a,
145        Self::Node: 'a;
146    fn intersection<'a>(&'a self, key: &'a keyexpr) -> Self::Intersection<'a> {
147        super::FilterMap::new(self.iter(), super::Intersection(key))
148    }
149    type IntersectionMut<'a>
150        = super::FilterMap<IterMut<'a, OwnedKeyExpr, T>, super::Intersection<'a>>
151    where
152        Self: 'a,
153        Self::Node: 'a;
154    fn intersection_mut<'a>(&'a mut self, key: &'a keyexpr) -> Self::IntersectionMut<'a> {
155        super::FilterMap::new(self.iter_mut(), super::Intersection(key))
156    }
157    type Inclusion<'a>
158        = super::FilterMap<Iter<'a, OwnedKeyExpr, T>, super::Inclusion<'a>>
159    where
160        Self: 'a,
161        Self::Node: 'a;
162    fn inclusion<'a>(&'a self, key: &'a keyexpr) -> Self::Inclusion<'a> {
163        super::FilterMap::new(self.iter(), super::Inclusion(key))
164    }
165    type InclusionMut<'a>
166        = super::FilterMap<IterMut<'a, OwnedKeyExpr, T>, super::Inclusion<'a>>
167    where
168        Self: 'a,
169        Self::Node: 'a;
170    fn inclusion_mut<'a>(&'a mut self, key: &'a keyexpr) -> Self::InclusionMut<'a> {
171        super::FilterMap::new(self.iter_mut(), super::Inclusion(key))
172    }
173}