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))]
35#[derive(Debug)]
36pub struct HashMapProvider<Hash: Hasher + Default + 'static = DefaultHasher>(
37    core::marker::PhantomData<Hash>,
38);
39impl<T: 'static, Hash: Hasher + Default + 'static> IChildrenProvider<T> for HashMapProvider<Hash> {
40    type Assoc = HashMap<OwnedKeyExpr, T, core::hash::BuildHasherDefault<Hash>>;
41}
42
43#[cfg(not(feature = "std"))]
44impl<'a: 'b, 'b, T: HasChunk, S: core::hash::BuildHasher> IEntry<'a, 'b, T>
45    for Entry<'a, OwnedKeyExpr, T, S>
46{
47    fn get_or_insert_with<F: FnOnce(&'b keyexpr) -> T>(self, f: F) -> &'a mut T {
48        match self {
49            Entry::Vacant(entry) => {
50                // SAFETY: upheld by the surrounding invariants and prior validation.
51                let value = unsafe { f(core::mem::transmute::<&keyexpr, &keyexpr>(entry.key())) };
52                entry.insert(value)
53            }
54            Entry::Occupied(v) => v.into_mut(),
55        }
56    }
57}
58#[cfg(feature = "std")]
59impl<'a: 'b, 'b, T: HasChunk> IEntry<'a, 'b, T> for Entry<'a, OwnedKeyExpr, T> {
60    fn get_or_insert_with<F: FnOnce(&'b keyexpr) -> T>(self, f: F) -> &'a mut T {
61        match self {
62            Entry::Vacant(entry) => {
63                // SAFETY: upheld by the surrounding invariants and prior validation.
64                let value = unsafe { f(core::mem::transmute::<&keyexpr, &keyexpr>(entry.key())) };
65                entry.insert(value)
66            }
67            Entry::Occupied(v) => v.into_mut(),
68        }
69    }
70}
71
72impl<T: HasChunk + AsNode<T> + AsNodeMut<T> + 'static, S: core::hash::BuildHasher> IChildren<T>
73    for HashMap<OwnedKeyExpr, T, S>
74{
75    type Node = T;
76    fn child_at(&self, chunk: &keyexpr) -> Option<&T> {
77        self.get(chunk)
78    }
79    fn child_at_mut(&mut self, chunk: &keyexpr) -> Option<&mut T> {
80        self.get_mut(chunk)
81    }
82    fn remove(&mut self, chunk: &keyexpr) -> Option<Self::Node> {
83        self.remove(chunk)
84    }
85    fn len(&self) -> usize {
86        self.len()
87    }
88    fn is_empty(&self) -> bool {
89        self.is_empty()
90    }
91
92    #[cfg(feature = "std")]
93    type Entry<'a, 'b>
94        = Entry<'a, OwnedKeyExpr, T>
95    where
96        Self: 'a,
97        'a: 'b,
98        T: 'b;
99    #[cfg(not(feature = "std"))]
100    type Entry<'a, 'b>
101        = Entry<'a, OwnedKeyExpr, T, S>
102    where
103        Self: 'a,
104        'a: 'b,
105        T: 'b;
106    fn entry<'a, 'b>(&'a mut self, chunk: &'b keyexpr) -> Self::Entry<'a, 'b>
107    where
108        Self: 'a,
109        'a: 'b,
110        T: 'b,
111    {
112        self.entry(chunk.into())
113    }
114
115    type Iter<'a>
116        = Values<'a, OwnedKeyExpr, T>
117    where
118        Self: 'a;
119    fn children<'a>(&'a self) -> Self::Iter<'a>
120    where
121        Self: 'a,
122    {
123        self.values()
124    }
125
126    type IterMut<'a>
127        = ValuesMut<'a, OwnedKeyExpr, T>
128    where
129        Self: 'a;
130
131    fn children_mut<'a>(&'a mut self) -> Self::IterMut<'a>
132    where
133        Self: 'a,
134    {
135        self.values_mut()
136    }
137
138    fn filter_out<F: FnMut(&mut T) -> bool>(&mut self, predicate: &mut F) {
139        self.retain(|_, v| predicate(v));
140    }
141
142    type Intersection<'a>
143        = super::FilterMap<Iter<'a, OwnedKeyExpr, T>, super::Intersection<'a>>
144    where
145        Self: 'a,
146        Self::Node: 'a;
147    fn intersection<'a>(&'a self, key: &'a keyexpr) -> Self::Intersection<'a> {
148        super::FilterMap::new(self.iter(), super::Intersection(key))
149    }
150    type IntersectionMut<'a>
151        = super::FilterMap<IterMut<'a, OwnedKeyExpr, T>, super::Intersection<'a>>
152    where
153        Self: 'a,
154        Self::Node: 'a;
155    fn intersection_mut<'a>(&'a mut self, key: &'a keyexpr) -> Self::IntersectionMut<'a> {
156        super::FilterMap::new(self.iter_mut(), super::Intersection(key))
157    }
158    type Inclusion<'a>
159        = super::FilterMap<Iter<'a, OwnedKeyExpr, T>, super::Inclusion<'a>>
160    where
161        Self: 'a,
162        Self::Node: 'a;
163    fn inclusion<'a>(&'a self, key: &'a keyexpr) -> Self::Inclusion<'a> {
164        super::FilterMap::new(self.iter(), super::Inclusion(key))
165    }
166    type InclusionMut<'a>
167        = super::FilterMap<IterMut<'a, OwnedKeyExpr, T>, super::Inclusion<'a>>
168    where
169        Self: 'a,
170        Self::Node: 'a;
171    fn inclusion_mut<'a>(&'a mut self, key: &'a keyexpr) -> Self::InclusionMut<'a> {
172        super::FilterMap::new(self.iter_mut(), super::Inclusion(key))
173    }
174}