Add IndexedMap::get_key_value
[rust-lightning] / lightning / src / util / indexed_map.rs
index 3d45172517db3e706dcbf4884dd75923c872c8a5..97788ffe68acbd5f90d67bd501710c3b5942ce51 100644 (file)
@@ -1,10 +1,8 @@
 //! This module has a map which can be iterated in a deterministic order. See the [`IndexedMap`].
 
-use crate::prelude::{HashMap, hash_map};
-use alloc::vec::Vec;
+use crate::prelude::*;
 use alloc::slice::Iter;
 use core::hash::Hash;
-use core::cmp::Ord;
 use core::ops::{Bound, RangeBounds};
 
 /// A map which can be iterated in a deterministic order.
@@ -21,6 +19,8 @@ use core::ops::{Bound, RangeBounds};
 /// actually backed by a [`HashMap`], with some additional tracking to ensure we can iterate over
 /// keys in the order defined by [`Ord`].
 ///
+/// This is not exported to bindings users as bindings provide alternate accessors rather than exposing maps directly.
+///
 /// [`BTreeMap`]: alloc::collections::BTreeMap
 #[derive(Clone, Debug, Eq)]
 pub struct IndexedMap<K: Hash + Ord, V> {
@@ -32,11 +32,19 @@ impl<K: Clone + Hash + Ord, V> IndexedMap<K, V> {
        /// Constructs a new, empty map
        pub fn new() -> Self {
                Self {
-                       map: HashMap::new(),
+                       map: new_hash_map(),
                        keys: Vec::new(),
                }
        }
 
+       /// Constructs a new, empty map with the given capacity pre-allocated
+       pub fn with_capacity(capacity: usize) -> Self {
+               Self {
+                       map: hash_map_with_capacity(capacity),
+                       keys: Vec::with_capacity(capacity),
+               }
+       }
+
        #[inline(always)]
        /// Fetches the element with the given `key`, if one exists.
        pub fn get(&self, key: &K) -> Option<&V> {
@@ -48,6 +56,11 @@ impl<K: Clone + Hash + Ord, V> IndexedMap<K, V> {
                self.map.get_mut(key)
        }
 
+       /// Fetches the key-value pair corresponding to the supplied key, if one exists.
+       pub fn get_key_value(&self, key: &K) -> Option<(&K, &V)> {
+               self.map.get_key_value(key)
+       }
+
        #[inline]
        /// Returns true if an element with the given `key` exists in the map.
        pub fn contains_key(&self, key: &K) -> bool {
@@ -147,6 +160,8 @@ impl<K: Hash + Ord + PartialEq, V: PartialEq> PartialEq for IndexedMap<K, V> {
 }
 
 /// An iterator over a range of values in an [`IndexedMap`]
+///
+/// This is not exported to bindings users as bindings provide alternate accessors rather than exposing maps directly.
 pub struct Range<'a, K: Hash + Ord, V> {
        inner_range: Iter<'a, K>,
        map: &'a HashMap<K, V>,
@@ -161,26 +176,26 @@ impl<'a, K: Hash + Ord, V: 'a> Iterator for Range<'a, K, V> {
 }
 
 /// An [`Entry`] for a key which currently has no value
+///
+/// This is not exported to bindings users as bindings provide alternate accessors rather than exposing maps directly.
 pub struct VacantEntry<'a, K: Hash + Ord, V> {
-       #[cfg(feature = "hashbrown")]
-       underlying_entry: hash_map::VacantEntry<'a, K, V, hash_map::DefaultHashBuilder>,
-       #[cfg(not(feature = "hashbrown"))]
-       underlying_entry: hash_map::VacantEntry<'a, K, V>,
+       underlying_entry: VacantHashMapEntry<'a, K, V>,
        key: K,
        keys: &'a mut Vec<K>,
 }
 
 /// An [`Entry`] for an existing key-value pair
+///
+/// This is not exported to bindings users as bindings provide alternate accessors rather than exposing maps directly.
 pub struct OccupiedEntry<'a, K: Hash + Ord, V> {
-       #[cfg(feature = "hashbrown")]
-       underlying_entry: hash_map::OccupiedEntry<'a, K, V, hash_map::DefaultHashBuilder>,
-       #[cfg(not(feature = "hashbrown"))]
-       underlying_entry: hash_map::OccupiedEntry<'a, K, V>,
+       underlying_entry: OccupiedHashMapEntry<'a, K, V>,
        keys: &'a mut Vec<K>,
 }
 
 /// A mutable reference to a position in the map. This can be used to reference, add, or update the
 /// value at a fixed key.
+///
+/// This is not exported to bindings users as bindings provide alternate accessors rather than exposing maps directly.
 pub enum Entry<'a, K: Hash + Ord, V> {
        /// A mutable reference to a position within the map where there is no value.
        Vacant(VacantEntry<'a, K, V>),