Skip to content

Commit 71f7bdc

Browse files
authored
Implement nohash_hasher::IsEnabled for Id (#5628)
`egui::id::IdSet` and `egui::id::IdMap` were already optimized to not do additional hashing (because the `Id` already is a hash), but now they are just type aliases for `nohash_hasher::IntSet/IntMap`. See https://crates.io/crates/nohash-hasher for more
1 parent 493d5d0 commit 71f7bdc

File tree

2 files changed

+6
-73
lines changed

2 files changed

+6
-73
lines changed

crates/egui/src/id.rs

+4-71
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ use std::num::NonZeroU64;
3333
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
3434
pub struct Id(NonZeroU64);
3535

36+
impl nohash_hasher::IsEnabled for Id {}
37+
3638
impl Id {
3739
/// A special [`Id`], in particular as a key to [`crate::Memory::data`]
3840
/// for when there is no particular widget to attach the data.
@@ -112,77 +114,8 @@ fn id_size() {
112114

113115
// ----------------------------------------------------------------------------
114116

115-
// Idea taken from the `nohash_hasher` crate.
116-
#[derive(Default)]
117-
pub struct IdHasher(u64);
118-
119-
impl std::hash::Hasher for IdHasher {
120-
fn write(&mut self, _: &[u8]) {
121-
unreachable!("Invalid use of IdHasher");
122-
}
123-
124-
fn write_u8(&mut self, _n: u8) {
125-
unreachable!("Invalid use of IdHasher");
126-
}
127-
128-
fn write_u16(&mut self, _n: u16) {
129-
unreachable!("Invalid use of IdHasher");
130-
}
131-
132-
fn write_u32(&mut self, _n: u32) {
133-
unreachable!("Invalid use of IdHasher");
134-
}
135-
136-
#[inline(always)]
137-
fn write_u64(&mut self, n: u64) {
138-
self.0 = n;
139-
}
140-
141-
fn write_usize(&mut self, _n: usize) {
142-
unreachable!("Invalid use of IdHasher");
143-
}
144-
145-
fn write_i8(&mut self, _n: i8) {
146-
unreachable!("Invalid use of IdHasher");
147-
}
148-
149-
fn write_i16(&mut self, _n: i16) {
150-
unreachable!("Invalid use of IdHasher");
151-
}
152-
153-
fn write_i32(&mut self, _n: i32) {
154-
unreachable!("Invalid use of IdHasher");
155-
}
156-
157-
fn write_i64(&mut self, _n: i64) {
158-
unreachable!("Invalid use of IdHasher");
159-
}
160-
161-
fn write_isize(&mut self, _n: isize) {
162-
unreachable!("Invalid use of IdHasher");
163-
}
164-
165-
#[inline(always)]
166-
fn finish(&self) -> u64 {
167-
self.0
168-
}
169-
}
170-
171-
#[derive(Copy, Clone, Debug, Default)]
172-
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
173-
pub struct BuildIdHasher {}
174-
175-
impl std::hash::BuildHasher for BuildIdHasher {
176-
type Hasher = IdHasher;
177-
178-
#[inline(always)]
179-
fn build_hasher(&self) -> IdHasher {
180-
IdHasher::default()
181-
}
182-
}
183-
184117
/// `IdSet` is a `HashSet<Id>` optimized by knowing that [`Id`] has good entropy, and doesn't need more hashing.
185-
pub type IdSet = std::collections::HashSet<Id, BuildIdHasher>;
118+
pub type IdSet = nohash_hasher::IntSet<Id>;
186119

187120
/// `IdMap<V>` is a `HashMap<Id, V>` optimized by knowing that [`Id`] has good entropy, and doesn't need more hashing.
188-
pub type IdMap<V> = std::collections::HashMap<Id, V, BuildIdHasher>;
121+
pub type IdMap<V> = nohash_hasher::IntMap<Id, V>;

crates/egui/src/pass_state.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use ahash::{HashMap, HashSet};
1+
use ahash::HashMap;
22

33
use crate::{id::IdSet, style, Align, Id, IdMap, LayerId, Rangef, Rect, Vec2, WidgetRects};
44

@@ -34,7 +34,7 @@ pub struct PerLayerState {
3434
/// Is there any open popup (menus, combo-boxes, etc)?
3535
///
3636
/// Does NOT include tooltips.
37-
pub open_popups: HashSet<Id>,
37+
pub open_popups: IdSet,
3838

3939
/// Which widget is showing a tooltip (if any)?
4040
///

0 commit comments

Comments
 (0)