From b46737ff78b8cb02a15c6c9e409165cd171c134c Mon Sep 17 00:00:00 2001 From: qm3ster Date: Sun, 23 Jul 2023 22:48:12 +0300 Subject: [PATCH 1/3] Added _yes get_or_intern methods --- src/rodeo.rs | 147 ++++++++++++++++++++++++++++++++++++---- src/threaded_rodeo.rs | 154 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 272 insertions(+), 29 deletions(-) diff --git a/src/rodeo.rs b/src/rodeo.rs index 5c32a42..47a2551 100644 --- a/src/rodeo.rs +++ b/src/rodeo.rs @@ -291,6 +291,42 @@ where .expect("Failed to get or intern string") } + /// Get a boolean signifying whether the string is previously unseen and the key for it, interning it if it is + /// + /// # Panics + /// + /// Panics if the key's `try_from_usize` function fails. With the default keys, this means that + /// you've interned more strings than it can handle. (For [`Spur`] this means that `u32::MAX - 1` + /// unique strings were interned) + /// + /// # Example + /// + /// ```rust + /// use lasso::Rodeo; + /// + /// let mut rodeo = Rodeo::default(); + /// + /// // Interned the string + /// let (is_new, key) = rodeo.get_or_intern_yes("Strings of things with wings and dings"); + /// assert!(is_new); + /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); + /// + /// // No string was interned, as it was already contained + /// let (is_new, key) = rodeo.get_or_intern_yes("Strings of things with wings and dings"); + /// assert!(!is_new); + /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); + /// ``` + /// + /// [`Spur`]: crate::Spur + #[cfg_attr(feature = "inline-more", inline)] + pub fn get_or_intern_yes(&mut self, val: T) -> (bool, K) + where + T: AsRef, + { + self.try_get_or_intern_yes(val) + .expect("Failed to get or intern string") + } + /// Get the key for a string, interning it if it does not yet exist /// /// # Example @@ -311,6 +347,34 @@ where /// #[cfg_attr(feature = "inline-more", inline)] pub fn try_get_or_intern(&mut self, val: T) -> LassoResult + where + T: AsRef, + { + self.try_get_or_intern_yes(val).map(|(_yes, key)| key) + } + + /// Get a boolean signifying whether the string is previously unseen and the key for it, interning it if it is + /// + /// # Example + /// + /// ```rust + /// use lasso::Rodeo; + /// + /// let mut rodeo = Rodeo::default(); + /// + /// // Interned the string + /// let (is_new, key) = rodeo.try_get_or_intern_yes("Strings of things with wings and dings").unwrap(); + /// assert!(is_new); + /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); + /// + /// // No string was interned, as it was already contained + /// let (is_new, key) = rodeo.try_get_or_intern_yes("Strings of things with wings and dings").unwrap(); + /// assert!(!is_new); + /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); + /// ``` + /// + #[cfg_attr(feature = "inline-more", inline)] + pub fn try_get_or_intern_yes(&mut self, val: T) -> LassoResult<(bool, K)> where T: AsRef, { @@ -327,9 +391,9 @@ where let hash = hash_string(hasher, string_slice); // Get the map's entry that the string should occupy - let key = match get_string_entry_mut(map, strings, hash, string_slice) { + match get_string_entry_mut(map, strings, hash, string_slice) { // The string already exists, so return its key - RawEntryMut::Occupied(entry) => *entry.into_key(), + RawEntryMut::Occupied(entry) => Ok((false, *entry.into_key())), // The string does not yet exist, so insert it and create its key RawEntryMut::Vacant(entry) => { @@ -347,11 +411,9 @@ where // Insert the key with the hash of the string that it points to, reusing the hash we made earlier insert_string(entry, strings, hasher, hash, key); - key + Ok((true, key)) } - }; - - Ok(key) + } } /// Get the key for a static string, interning it if it does not yet exist @@ -386,6 +448,41 @@ where .expect("Failed to get or intern static string") } + /// Get a boolean signifying whether the static string is previously unseen and the key for it, interning it if it is + /// + /// This will not reallocate or copy the given string + /// + /// # Panics + /// + /// Panics if the key's `try_from_usize` function fails. With the default keys, this means that + /// you've interned more strings than it can handle. (For [`Spur`] this means that `u32::MAX - 1` + /// unique strings were interned) + /// + /// # Example + /// + /// ```rust + /// use lasso::Rodeo; + /// + /// let mut rodeo = Rodeo::default(); + /// + /// // Interned the string + /// let (is_new, key) = rodeo.get_or_intern_static_yes("Strings of things with wings and dings"); + /// assert!(is_new); + /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); + /// + /// // No string was interned, as it was already contained + /// let (is_new, key) = rodeo.get_or_intern_static_yes("Strings of things with wings and dings"); + /// assert!(!is_new); + /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); + /// + /// ``` + /// + #[cfg_attr(feature = "inline-more", inline)] + pub fn get_or_intern_static_yes(&mut self, string: &'static str) -> (bool, K) { + self.try_get_or_intern_static_yes(string) + .expect("Failed to get or intern static string") + } + /// Get the key for a static string, interning it if it does not yet exist /// /// This will not reallocate or copy the given string @@ -408,6 +505,34 @@ where /// #[cfg_attr(feature = "inline-more", inline)] pub fn try_get_or_intern_static(&mut self, string: &'static str) -> LassoResult { + self.try_get_or_intern_static_yes(string) + .map(|(_yes, key)| key) + } + + /// Get a boolean signifying whether the static string is previously unseen and the key for it, interning it if it is + /// + /// This will not reallocate or copy the given string + /// + /// # Example + /// + /// ```rust + /// use lasso::Rodeo; + /// + /// let mut rodeo = Rodeo::default(); + /// + /// // Interned the string + /// let (is_new, key) = rodeo.try_get_or_intern_static_yes("Strings of things with wings and dings").unwrap(); + /// assert!(is_new); + /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); + /// + /// // No string was interned, as it was already contained + /// let (is_new, key) = rodeo.try_get_or_intern_static_yes("Strings of things with wings and dings").unwrap(); + /// assert!(!is_new); + /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); + /// ``` + /// + #[cfg_attr(feature = "inline-more", inline)] + pub fn try_get_or_intern_static_yes(&mut self, string: &'static str) -> LassoResult<(bool, K)> { let Self { map, hasher, @@ -419,9 +544,9 @@ where let hash = hash_string(hasher, string); // Get the map's entry that the string should occupy - let key = match get_string_entry_mut(map, strings, hash, string) { + match get_string_entry_mut(map, strings, hash, string) { // The string already exists, so return its key - RawEntryMut::Occupied(entry) => *entry.into_key(), + RawEntryMut::Occupied(entry) => Ok((false, *entry.into_key())), // The string does not yet exist, so insert it and create its key RawEntryMut::Vacant(entry) => { @@ -435,11 +560,9 @@ where // Insert the key with the hash of the string that it points to, reusing the hash we made earlier insert_string(entry, strings, hasher, hash, key); - key + Ok((true, key)) } - }; - - Ok(key) + } } /// Get the key value of a string, returning `None` if it doesn't exist diff --git a/src/threaded_rodeo.rs b/src/threaded_rodeo.rs index 51a27d4..5a6e0cd 100644 --- a/src/threaded_rodeo.rs +++ b/src/threaded_rodeo.rs @@ -290,6 +290,41 @@ where .expect("Failed to get or intern string") } + /// Get a boolean signifying whether the string is previously unseen and the key for it, interning it if it is + /// + /// # Panics + /// + /// Panics if the key's `try_from_usize` function fails. With the default keys, this means that + /// you've interned more strings than it can handle. (For [`Spur`] this means that `u32::MAX - 1` + /// unique strings were interned) + /// + /// # Example + /// + /// ```rust + /// use lasso::ThreadedRodeo; + /// + /// let rodeo = ThreadedRodeo::default(); + /// + /// // Interned the string + /// let (is_new, key) = rodeo.get_or_intern_yes("Strings of things with wings and dings"); + /// assert!(is_new); + /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); + /// + /// // No string was interned, as it was already contained + /// let (is_new, key) = rodeo.get_or_intern_yes("Strings of things with wings and dings"); + /// assert!(!is_new); + /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); + /// ``` + /// + #[cfg_attr(feature = "inline-more", inline)] + pub fn get_or_intern_yes(&self, val: T) -> (bool, K) + where + T: AsRef, + { + self.try_get_or_intern_yes(val) + .expect("Failed to get or intern string") + } + /// Get the key for a string, interning it if it does not yet exist /// /// # Example @@ -310,39 +345,65 @@ where /// #[cfg_attr(feature = "inline-more", inline)] pub fn try_get_or_intern(&self, val: T) -> LassoResult + where + T: AsRef, + { + self.try_get_or_intern_yes(val).map(|(_yes, key)| key) + } + + /// Get a boolean signifying whether the string is previously unseen and the key for it, interning it if it is + /// + /// # Example + /// + /// ```rust + /// use lasso::ThreadedRodeo; + /// + /// let rodeo = ThreadedRodeo::default(); + /// + /// // Interned the string + /// let (is_new, key) = rodeo.get_or_intern_yes("Strings of things with wings and dings"); + /// assert!(is_new); + /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); + /// + /// // No string was interned, as it was already contained + /// let (is_new, key) = rodeo.get_or_intern_yes("Strings of things with wings and dings"); + /// assert!(!is_new); + /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); + /// ``` + /// + #[cfg_attr(feature = "inline-more", inline)] + pub fn try_get_or_intern_yes(&self, val: T) -> LassoResult<(bool, K)> where T: AsRef, { let string_slice = val.as_ref(); if let Some(key) = self.map.get(string_slice) { - Ok(*key) + Ok((false, *key)) } else { // Determine which shard will have our `string_slice` key. let shard_key = self.map.determine_shard(self.map.hash_usize(&string_slice)); // Grab the shard and a write lock on it. let mut shard = self.map.shards().get(shard_key).unwrap().write(); - // Try getting the value for the `string_slice` key. If we get `Some`, nothing to do. - // Just return the value, which is the key go to use to resolve the string. If we + // Try getting the value for the `string_slice` key. If we get `Some`, nothing to do. + // Just return the value, which is the key go to use to resolve the string. If we // get `None`, an entry for the string doesn't exist yet. Store string in the arena, // update the maps accordingly, and return the key. - let key = match shard.get(string_slice) { - Some(v) => *v.get(), + match shard.get(string_slice) { + Some(v) => Ok((false, *v.get())), None => { // Safety: The drop impl removes all references before the arena is dropped let string: &'static str = unsafe { self.arena.store_str(string_slice)? }; - + let key = K::try_from_usize(self.key.fetch_add(1, Ordering::SeqCst)) .ok_or_else(|| LassoError::new(LassoErrorKind::KeySpaceExhaustion))?; - + self.strings.insert(key, string); shard.insert(string, SharedValue::new(key)); - key + Ok((true, key)) } - }; - - Ok(key) + } } } @@ -378,6 +439,40 @@ where .expect("Failed to get or intern static string") } + /// Get a boolean signifying whether the static string is previously unseen and the key for it, interning it if it is + /// + /// This will not reallocate or copy the given string but will instead just store it + /// + /// # Panics + /// + /// Panics if the key's `try_from_usize` function fails. With the default keys, this means that + /// you've interned more strings than it can handle. (For [`Spur`] this means that `u32::MAX - 1` + /// unique strings were interned) + /// + /// # Example + /// + /// ```rust + /// use lasso::ThreadedRodeo; + /// + /// let mut rodeo = ThreadedRodeo::default(); + /// + /// // Interned the string + /// let (is_new, key) = rodeo.get_or_intern_static_yes("Strings of things with wings and dings"); + /// assert!(is_new); + /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); + /// + /// // No string was interned, as it was already contained + /// let (is_new, key) = rodeo.get_or_intern_static_yes("Strings of things with wings and dings"); + /// assert!(!is_new); + /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); + /// ``` + /// + #[cfg_attr(feature = "inline-more", inline)] + pub fn get_or_intern_static_yes(&self, string: &'static str) -> (bool, K) { + self.try_get_or_intern_static_yes(string) + .expect("Failed to get or intern static string") + } + /// Get the key for a static string, interning it if it does not yet exist /// /// This will not reallocate and copy the given string but will instead just store it @@ -400,14 +495,39 @@ where /// #[cfg_attr(feature = "inline-more", inline)] pub fn try_get_or_intern_static(&self, string: &'static str) -> LassoResult { + self.try_get_or_intern_static_yes(string) + .map(|(_yes, key)| key) + } + + /// Get a boolean signifying whether the static string is previously unseen and the key for it, interning it if it is + /// + /// This will not reallocate and copy the given string but will instead just store it + /// + /// # Example + /// + /// ```rust + /// use lasso::ThreadedRodeo; + /// + /// let mut rodeo = ThreadedRodeo::default(); + /// + /// // Interned the string + /// let (is_new, key) = rodeo.try_get_or_intern_static_yes("Strings of things with wings and dings").unwrap(); + /// assert!(is_new); + /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); + /// + /// // No string was interned, as it was already contained + /// let (is_new, key) = rodeo.try_get_or_intern_static_yes("Strings of things with wings and dings").unwrap(); + /// assert!(!is_new); + /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); + /// ``` + /// + #[cfg_attr(feature = "inline-more", inline)] + pub fn try_get_or_intern_static_yes(&self, string: &'static str) -> LassoResult<(bool, K)> { if let Some(key) = self.map.get(string) { - Ok(*key) + Ok((false, *key)) } else { - let key = match self.map.entry(string) { - Entry::Occupied(o) => { - *o.get() - } + Entry::Occupied(o) => *o.get(), Entry::Vacant(v) => { let key = K::try_from_usize(self.key.fetch_add(1, Ordering::SeqCst)) .ok_or_else(|| LassoError::new(LassoErrorKind::KeySpaceExhaustion))?; @@ -418,7 +538,7 @@ where } }; - Ok(key) + Ok((true, key)) } } From a6154cf229b8c2ff19fb601f8706bef2dbc07586 Mon Sep 17 00:00:00 2001 From: qm3ster Date: Sun, 23 Jul 2023 23:48:45 +0300 Subject: [PATCH 2/3] Rename `get_or_intern_yes` to `insert` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also let rustfmt sort the dashmap imports 😬 --- src/rodeo.rs | 33 ++++++++++++++++----------------- src/threaded_rodeo.rs | 35 +++++++++++++++++------------------ 2 files changed, 33 insertions(+), 35 deletions(-) diff --git a/src/rodeo.rs b/src/rodeo.rs index 47a2551..2fb7ea1 100644 --- a/src/rodeo.rs +++ b/src/rodeo.rs @@ -307,23 +307,23 @@ where /// let mut rodeo = Rodeo::default(); /// /// // Interned the string - /// let (is_new, key) = rodeo.get_or_intern_yes("Strings of things with wings and dings"); + /// let (is_new, key) = rodeo.insert("Strings of things with wings and dings"); /// assert!(is_new); /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); /// /// // No string was interned, as it was already contained - /// let (is_new, key) = rodeo.get_or_intern_yes("Strings of things with wings and dings"); + /// let (is_new, key) = rodeo.insert("Strings of things with wings and dings"); /// assert!(!is_new); /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); /// ``` /// /// [`Spur`]: crate::Spur #[cfg_attr(feature = "inline-more", inline)] - pub fn get_or_intern_yes(&mut self, val: T) -> (bool, K) + pub fn insert(&mut self, val: T) -> (bool, K) where T: AsRef, { - self.try_get_or_intern_yes(val) + self.try_insert(val) .expect("Failed to get or intern string") } @@ -350,7 +350,7 @@ where where T: AsRef, { - self.try_get_or_intern_yes(val).map(|(_yes, key)| key) + self.try_insert(val).map(|(_yes, key)| key) } /// Get a boolean signifying whether the string is previously unseen and the key for it, interning it if it is @@ -363,18 +363,18 @@ where /// let mut rodeo = Rodeo::default(); /// /// // Interned the string - /// let (is_new, key) = rodeo.try_get_or_intern_yes("Strings of things with wings and dings").unwrap(); + /// let (is_new, key) = rodeo.try_insert("Strings of things with wings and dings").unwrap(); /// assert!(is_new); /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); /// /// // No string was interned, as it was already contained - /// let (is_new, key) = rodeo.try_get_or_intern_yes("Strings of things with wings and dings").unwrap(); + /// let (is_new, key) = rodeo.try_insert("Strings of things with wings and dings").unwrap(); /// assert!(!is_new); /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); /// ``` /// #[cfg_attr(feature = "inline-more", inline)] - pub fn try_get_or_intern_yes(&mut self, val: T) -> LassoResult<(bool, K)> + pub fn try_insert(&mut self, val: T) -> LassoResult<(bool, K)> where T: AsRef, { @@ -466,20 +466,20 @@ where /// let mut rodeo = Rodeo::default(); /// /// // Interned the string - /// let (is_new, key) = rodeo.get_or_intern_static_yes("Strings of things with wings and dings"); + /// let (is_new, key) = rodeo.insert_static("Strings of things with wings and dings"); /// assert!(is_new); /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); /// /// // No string was interned, as it was already contained - /// let (is_new, key) = rodeo.get_or_intern_static_yes("Strings of things with wings and dings"); + /// let (is_new, key) = rodeo.insert_static("Strings of things with wings and dings"); /// assert!(!is_new); /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); /// /// ``` /// #[cfg_attr(feature = "inline-more", inline)] - pub fn get_or_intern_static_yes(&mut self, string: &'static str) -> (bool, K) { - self.try_get_or_intern_static_yes(string) + pub fn insert_static(&mut self, string: &'static str) -> (bool, K) { + self.try_insert_static(string) .expect("Failed to get or intern static string") } @@ -505,8 +505,7 @@ where /// #[cfg_attr(feature = "inline-more", inline)] pub fn try_get_or_intern_static(&mut self, string: &'static str) -> LassoResult { - self.try_get_or_intern_static_yes(string) - .map(|(_yes, key)| key) + self.try_insert_static(string).map(|(_yes, key)| key) } /// Get a boolean signifying whether the static string is previously unseen and the key for it, interning it if it is @@ -521,18 +520,18 @@ where /// let mut rodeo = Rodeo::default(); /// /// // Interned the string - /// let (is_new, key) = rodeo.try_get_or_intern_static_yes("Strings of things with wings and dings").unwrap(); + /// let (is_new, key) = rodeo.try_insert_static("Strings of things with wings and dings").unwrap(); /// assert!(is_new); /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); /// /// // No string was interned, as it was already contained - /// let (is_new, key) = rodeo.try_get_or_intern_static_yes("Strings of things with wings and dings").unwrap(); + /// let (is_new, key) = rodeo.try_insert_static("Strings of things with wings and dings").unwrap(); /// assert!(!is_new); /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); /// ``` /// #[cfg_attr(feature = "inline-more", inline)] - pub fn try_get_or_intern_static_yes(&mut self, string: &'static str) -> LassoResult<(bool, K)> { + pub fn try_insert_static(&mut self, string: &'static str) -> LassoResult<(bool, K)> { let Self { map, hasher, diff --git a/src/threaded_rodeo.rs b/src/threaded_rodeo.rs index 5a6e0cd..f7f5b36 100644 --- a/src/threaded_rodeo.rs +++ b/src/threaded_rodeo.rs @@ -13,7 +13,7 @@ use core::{ ops::Index, sync::atomic::{AtomicUsize, Ordering}, }; -use dashmap::{DashMap, mapref::entry::Entry, SharedValue}; +use dashmap::{mapref::entry::Entry, DashMap, SharedValue}; use hashbrown::{hash_map::RawEntryMut, HashMap}; macro_rules! index_unchecked_mut { @@ -306,22 +306,22 @@ where /// let rodeo = ThreadedRodeo::default(); /// /// // Interned the string - /// let (is_new, key) = rodeo.get_or_intern_yes("Strings of things with wings and dings"); + /// let (is_new, key) = rodeo.insert("Strings of things with wings and dings"); /// assert!(is_new); /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); /// /// // No string was interned, as it was already contained - /// let (is_new, key) = rodeo.get_or_intern_yes("Strings of things with wings and dings"); + /// let (is_new, key) = rodeo.insert("Strings of things with wings and dings"); /// assert!(!is_new); /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); /// ``` /// #[cfg_attr(feature = "inline-more", inline)] - pub fn get_or_intern_yes(&self, val: T) -> (bool, K) + pub fn insert(&self, val: T) -> (bool, K) where T: AsRef, { - self.try_get_or_intern_yes(val) + self.try_insert(val) .expect("Failed to get or intern string") } @@ -348,7 +348,7 @@ where where T: AsRef, { - self.try_get_or_intern_yes(val).map(|(_yes, key)| key) + self.try_insert(val).map(|(_yes, key)| key) } /// Get a boolean signifying whether the string is previously unseen and the key for it, interning it if it is @@ -361,18 +361,18 @@ where /// let rodeo = ThreadedRodeo::default(); /// /// // Interned the string - /// let (is_new, key) = rodeo.get_or_intern_yes("Strings of things with wings and dings"); + /// let (is_new, key) = rodeo.insert("Strings of things with wings and dings"); /// assert!(is_new); /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); /// /// // No string was interned, as it was already contained - /// let (is_new, key) = rodeo.get_or_intern_yes("Strings of things with wings and dings"); + /// let (is_new, key) = rodeo.insert("Strings of things with wings and dings"); /// assert!(!is_new); /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); /// ``` /// #[cfg_attr(feature = "inline-more", inline)] - pub fn try_get_or_intern_yes(&self, val: T) -> LassoResult<(bool, K)> + pub fn try_insert(&self, val: T) -> LassoResult<(bool, K)> where T: AsRef, { @@ -457,19 +457,19 @@ where /// let mut rodeo = ThreadedRodeo::default(); /// /// // Interned the string - /// let (is_new, key) = rodeo.get_or_intern_static_yes("Strings of things with wings and dings"); + /// let (is_new, key) = rodeo.insert_static("Strings of things with wings and dings"); /// assert!(is_new); /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); /// /// // No string was interned, as it was already contained - /// let (is_new, key) = rodeo.get_or_intern_static_yes("Strings of things with wings and dings"); + /// let (is_new, key) = rodeo.insert_static("Strings of things with wings and dings"); /// assert!(!is_new); /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); /// ``` /// #[cfg_attr(feature = "inline-more", inline)] - pub fn get_or_intern_static_yes(&self, string: &'static str) -> (bool, K) { - self.try_get_or_intern_static_yes(string) + pub fn insert_static(&self, string: &'static str) -> (bool, K) { + self.try_insert_static(string) .expect("Failed to get or intern static string") } @@ -495,8 +495,7 @@ where /// #[cfg_attr(feature = "inline-more", inline)] pub fn try_get_or_intern_static(&self, string: &'static str) -> LassoResult { - self.try_get_or_intern_static_yes(string) - .map(|(_yes, key)| key) + self.try_insert_static(string).map(|(_yes, key)| key) } /// Get a boolean signifying whether the static string is previously unseen and the key for it, interning it if it is @@ -511,18 +510,18 @@ where /// let mut rodeo = ThreadedRodeo::default(); /// /// // Interned the string - /// let (is_new, key) = rodeo.try_get_or_intern_static_yes("Strings of things with wings and dings").unwrap(); + /// let (is_new, key) = rodeo.try_insert_static("Strings of things with wings and dings").unwrap(); /// assert!(is_new); /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); /// /// // No string was interned, as it was already contained - /// let (is_new, key) = rodeo.try_get_or_intern_static_yes("Strings of things with wings and dings").unwrap(); + /// let (is_new, key) = rodeo.try_insert_static("Strings of things with wings and dings").unwrap(); /// assert!(!is_new); /// assert_eq!("Strings of things with wings and dings", rodeo.resolve(&key)); /// ``` /// #[cfg_attr(feature = "inline-more", inline)] - pub fn try_get_or_intern_static_yes(&self, string: &'static str) -> LassoResult<(bool, K)> { + pub fn try_insert_static(&self, string: &'static str) -> LassoResult<(bool, K)> { if let Some(key) = self.map.get(string) { Ok((false, *key)) } else { From c4ca370dc457db4bd4ba5842bbe46a2af6a0f5ad Mon Sep 17 00:00:00 2001 From: qm3ster Date: Mon, 24 Jul 2023 00:23:50 +0300 Subject: [PATCH 3/3] Add `Rodeo::as_str` This is a horrendous stability guarantee, as the string slice storage is now guaranteed. Also, it should probably be called something else. --- src/rodeo.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/rodeo.rs b/src/rodeo.rs index 2fb7ea1..fee73e0 100644 --- a/src/rodeo.rs +++ b/src/rodeo.rs @@ -883,6 +883,13 @@ impl Rodeo { Strings::from_rodeo(self) } + /// Returns a reference to the slice of interned strings + #[cfg_attr(feature = "inline-more", inline)] + pub fn as_str(&self) -> &[&str] { + // Safety: we are shortening the &str lifetime from static to self, so they won't outlive the arens + &self.strings + } + /// Set the `Rodeo`'s maximum memory usage while in-flight /// /// Note that setting the maximum memory usage to below the currently allocated