deepmesa_collections/lhmap/
lhmap.rs

1/*
2   LinkedHashMap: A fast and flexible linked HashMap that allows for
3   O(1) inserts and removes with a predictable iteration order.
4
5   Copyright 2021 "Rahul Singh <rsingh@arrsingh.com>"
6
7   Licensed under the Apache License, Version 2.0 (the "License");
8   you may not use this file except in compliance with the License.
9   You may obtain a copy of the License at
10
11       http://www.apache.org/licenses/LICENSE-2.0
12
13   Unless required by applicable law or agreed to in writing, software
14   distributed under the License is distributed on an "AS IS" BASIS,
15   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   See the License for the specific language governing permissions and
17   limitations under the License.
18*/
19
20use crate::lhmap::entry::Entry;
21use crate::lhmap::entry::EntryHandle;
22use crate::lhmap::entry::Order;
23use crate::lhmap::entry::PtrKey;
24use crate::lhmap::iter::Iter;
25use crate::lhmap::iter::IterMut;
26use crate::lhmap::iter::Keys;
27use crate::lhmap::iter::Values;
28use crate::lhmap::iter::ValuesMut;
29use crate::linkedlist::list::LinkedList;
30use crate::linkedlist::node::NodeHandle;
31use core::hash::Hash;
32use std::collections::HashMap;
33
34/// A fast and flexible LinkedHashMap that combines a [`std::collections::HashMap`] and a
35/// [`LinkedList`](LinkedList) for *O*(*1*) inserts, lookups and deletes along with a
36/// predictable iteration order.
37///
38/// All the basic functions - [`get()`](#method.get),
39/// [`get_mut()`](#method.get_mut),
40/// [`get_key_value()`](#method.get_key_value),
41/// [`put()`](#method.put), [`insert()`](#method.insert),
42/// [`remove()`](#method.remove),
43/// [`remove_entry()`](#method.remove_entry) - provide constant time
44/// performance which is expected to be lower than that of the Hashmap
45/// given the added expense of of maintaining and updating the
46/// underlying linked list.
47///
48/// # Getting Started
49/// ```
50/// use deepmesa_collections::LinkedHashMap;
51/// use deepmesa_collections::lhmap::Order;
52///
53/// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
54/// lhm.put(1, "a");
55/// lhm.put(2, "b");
56///
57/// assert_eq!(lhm.get(&1), Some(&"a"));
58/// assert_eq!(lhm.get(&2), Some(&"b"));
59///
60/// if let Some(val) = lhm.get_mut(&1) {
61///     *val = "d";
62/// }
63///
64/// assert_eq!(lhm.get(&1), Some(&"d"));
65///
66/// ```
67///
68/// # Iteration Order
69///
70/// This map holds a LinkedList of all the elements that defines the
71/// iteration order. The order is either [`InsertionOrder`](Order) or
72/// [`AccessOrder`](Order). InsertionOrder is the order in which the
73/// keys were inserted into the map from least recently inserted
74/// (oldest) to most recently inserted (newest). ReInserting a key
75/// (via the insert or put methods) will change the insertion order to
76/// make the re-inserted key the most recently inserted (newest) in
77/// the order.
78///
79/// AccessOrder is the order in which the keys in the map were last
80/// accessed (via the [`get()`](#method.get),
81/// [`get_key_value()`](#method.get_key_value),
82/// [`get_mut()`](#method.get_mut) methods) from least-recently
83/// accessed (oldest) to most recently accessed (newest). Iterating
84/// over the map using one of the iterators -
85/// [`iter()`](#method.iter), [`iter_mut()`](#method.iter_mut),
86/// [`keys()`](#method.keys), [`values()`](#method.values),
87/// [`values_mut()`](#method.values_mut) - does not affect the order.
88///
89/// Iteration over the map requires time proportional to the length of
90/// the map (*O*(*len*)) regardless of the capacity because it
91/// iterates over the elements of the underlying linked list. The
92/// iteration order of the map is always from oldest entry (accessed
93/// or inserted) to the newest entry (accessed or inserted).
94///
95/// The map offers iterators over the [`elements`](#method.iter),
96/// [`keys`](#method.keys) and [`values`](#method.values) with mutable
97/// iterators for [`elements`](#method.iter_mut) and
98/// [`values`](#method.values_mut). The iterators can also be
99/// reversed.
100///
101/// ```
102/// // Construct a map in InsertionOrder
103/// use deepmesa_collections::LinkedHashMap;
104/// use deepmesa_collections::lhmap::Order;
105///
106/// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
107/// lhm.put(1, "a");
108/// lhm.put(2, "b");
109///
110/// lhm.get(&1);
111///
112/// let mut iter = lhm.iter();
113/// assert_eq!(iter.next(), Some((&1, &"a")));
114/// assert_eq!(iter.next(), Some((&2, &"b")));
115/// assert_eq!(iter.next(), None);
116/// iter = iter.reverse();
117/// assert_eq!(iter.next(), Some((&2, &"b")));
118/// assert_eq!(iter.next(), Some((&1, &"a")));
119/// assert_eq!(iter.next(), None);
120///
121///
122/// // Construct a map in AccessOrder
123/// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
124/// lhm.put(1, "a");
125/// lhm.put(2, "b");
126///
127/// lhm.get(&1);
128///
129/// let mut iter = lhm.iter();
130/// assert_eq!(iter.next(), Some((&2, &"b")));
131/// assert_eq!(iter.next(), Some((&1, &"a")));
132/// assert_eq!(iter.next(), None);
133/// iter = iter.reverse();
134/// assert_eq!(iter.next(), Some((&1, &"a")));
135/// assert_eq!(iter.next(), Some((&2, &"b")));
136/// assert_eq!(iter.next(), None);
137///
138/// ```
139///
140/// # Evicting Elements
141///
142/// The Map also supports construction with an
143/// [`evict_eldest`](#method.new) function that can be provided to
144/// implement a policy for removing entries when new elements are
145/// added to the map. A LinkedHashMap with [`AccessOrder`](Order) and
146/// an eviction function is well suited to building an LRU Cache.
147///
148/// ```
149/// use deepmesa_collections::lhmap::Entry;
150/// pub fn evict<K,V>(len: usize, capacity: usize, e: &Entry<K, V>) -> bool {
151///     if len > capacity {
152///         return true;
153///     }
154///     return false;
155/// }
156///
157/// use deepmesa_collections::LinkedHashMap;
158/// use deepmesa_collections::lhmap::Order;
159///
160/// let mut lhm = LinkedHashMap::<u16, &str>::new(3, Order::AccessOrder, Some(evict));
161/// lhm.put(1, "a");
162/// lhm.put(2, "b");
163/// lhm.put(3, "c");
164///
165/// assert_eq!(lhm.get(&2), Some(&"b"));
166/// lhm.put(4, "d");
167/// assert_eq!(lhm.get(&1), None);
168///
169/// ```
170/// 
171/// # Head/Tail Semantics
172/// 
173/// This LinkedHashMap uses the following head/tail semantics:
174/// - **Head**: Contains the oldest elements (least recently inserted/accessed)
175/// - **Tail**: Contains the newest elements (most recently inserted/accessed)
176/// - **Iteration**: Always proceeds from head to tail (oldest to newest)
177/// - **Eviction**: Removes elements from the head (oldest elements first)
178/// 
179/// New elements are added to the tail, and in AccessOrder mode, accessed 
180/// elements are moved to the tail (marking them as most recently used).
181pub struct LinkedHashMap<K, V>
182where
183    K: Hash + Eq,
184{
185    pub(crate) evict_eldest: Option<fn(len: usize, capacity: usize, e: &Entry<K, V>) -> bool>,
186    pub(crate) order: Order,
187    pub(crate) cap: usize,
188    pub(crate) ll: LinkedList<Entry<K, V>>,
189    pub(crate) map: HashMap<PtrKey<K>, NodeHandle<Entry<K, V>>>,
190}
191
192unsafe impl<K, V> Send for LinkedHashMap<K, V> where K: Hash + Eq {}
193unsafe impl<K, V> Sync for LinkedHashMap<K, V> where K: Hash + Eq {}
194
195impl<'a, K, V> IntoIterator for &'a LinkedHashMap<K, V>
196where
197    K: Hash + Eq,
198{
199    type Item = (&'a K, &'a V);
200    type IntoIter = Iter<'a, K, V>;
201    fn into_iter(self) -> Self::IntoIter {
202        self.iter()
203    }
204}
205
206impl<'a, K, V> IntoIterator for &'a mut LinkedHashMap<K, V>
207where
208    K: Hash + Eq,
209{
210    type Item = (&'a K, &'a mut V);
211    type IntoIter = IterMut<'a, K, V>;
212    fn into_iter(self) -> Self::IntoIter {
213        self.iter_mut()
214    }
215}
216
217impl<K, V> LinkedHashMap<K, V>
218where
219    K: Hash + Eq,
220{
221    /// Creates an empty LinkedHashMap with the specified capacity and
222    /// iteration order. The evict_eldest function can be supplied
223    /// that is called everytime a new entry is inserted into the map
224    /// with the current length, capacity and the first entry in the
225    /// linkedlist (least recently inserted or accessed).
226    ///
227    /// # Examples
228    ///
229    /// ```
230    /// use deepmesa_collections::LinkedHashMap;
231    /// use deepmesa_collections::lhmap::Order;
232    /// let lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
233    /// ```
234    pub fn new(
235        capacity: usize,
236        order: Order,
237        evict_eldest: Option<fn(len: usize, capacity: usize, e: &Entry<K, V>) -> bool>,
238    ) -> LinkedHashMap<K, V> {
239        return LinkedHashMap {
240            evict_eldest,
241            order,
242            cap: capacity,
243            map: HashMap::with_capacity(capacity),
244            ll: LinkedList::with_capacity(capacity),
245        };
246    }
247
248    /// Creates an empty LinkedHashMap with the specified capacity and
249    /// InsertionOrder. The underlying list will continue to
250    /// reallocate additional memory by doubling the capacity
251    /// everytime the capacity is exceeded. However the list will not
252    /// deallocate memory when keys are removed.
253    ///
254    /// If the capacity is set to 0, and the underlying list is full,
255    /// then new memory will be allocated for one new element
256    /// everytime an element is added to the list.
257    ///
258    /// The underlying hashmap will only allocate memory if the
259    /// capacity is greater than zero.
260    ///
261    /// # Examples
262    /// ```
263    /// use deepmesa_collections::LinkedHashMap;
264    /// let lhm = LinkedHashMap::<u16, &str>::with_capacity(10);
265    /// assert_eq!(lhm.capacity(), 10);
266    /// assert_eq!(lhm.len(), 0);
267    ///
268    /// ```
269    pub fn with_capacity(capacity: usize) -> LinkedHashMap<K, V> {
270        return Self::new(capacity, Order::InsertionOrder, None);
271    }
272
273    /// Returns the number of elements the map can hold before new
274    /// memory is allocated.
275    ///
276    /// # Examples
277    /// ```
278    /// use deepmesa_collections::LinkedHashMap;
279    /// use deepmesa_collections::lhmap::Order;
280    ///
281    /// let lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
282    /// assert_eq!(10, lhm.capacity());
283    /// assert_eq!(0, lhm.len());
284    /// ```
285    pub fn capacity(&self) -> usize {
286        return self.cap;
287    }
288
289    /// Returns the number or elements in the map.
290    ///
291    /// # Examples
292    /// ```
293    /// use deepmesa_collections::LinkedHashMap;
294    /// use deepmesa_collections::lhmap::Order;
295    ///
296    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
297    /// assert_eq!(lhm.len(), 0);
298    /// lhm.insert(1, "a");
299    /// assert_eq!(lhm.len(), 1);
300    ///
301    /// ```
302    pub fn len(&self) -> usize {
303        return self.map.len();
304    }
305
306    /// Removes and drops all the key-value pairs this map. This has
307    /// no effect on the allocated capacity of the map or the underlying list.
308    ///
309    /// This method should complete in *O*(*n*) time.
310    ///
311    /// # Examples
312    /// ```
313    /// use deepmesa_collections::LinkedHashMap;
314    /// use deepmesa_collections::lhmap::Order;
315    ///
316    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
317    /// lhm.insert(1, "a");
318    /// lhm.clear();
319    /// assert!(lhm.is_empty());
320    ///
321    /// ```
322    pub fn clear(&mut self) {
323        self.map.clear();
324        self.ll.clear();
325    }
326
327    /// Returns true if the map contains no elements and false otherwise.
328    /// This method should complete in *O*(*1*) time.
329    ///
330    /// # Examples
331    /// ```
332    /// use deepmesa_collections::LinkedHashMap;
333    /// use deepmesa_collections::lhmap::Order;
334    ///
335    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
336    /// assert!(lhm.is_empty());
337    /// lhm.insert(1, "a");
338    /// assert!(!lhm.is_empty());
339    ///
340    /// ```
341    pub fn is_empty(&self) -> bool {
342        return self.map.len() == 0;
343    }
344
345    /// Returns true if the map contains a value for the specified
346    /// key. This method should complete in *O*(*1*) time.
347    ///
348    /// # Examples
349    /// ```
350    /// use deepmesa_collections::LinkedHashMap;
351    /// use deepmesa_collections::lhmap::Order;
352    ///
353    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
354    /// lhm.insert(1, "a");
355    /// assert_eq!(lhm.contains_key(&1), true);
356    /// assert_eq!(lhm.contains_key(&2), false);
357    /// ```
358    pub fn contains_key(&self, key: &K) -> bool {
359        return self.map.contains_key(&PtrKey::new(key));
360    }
361
362    /// Returns a handle to the entry corresponding to the key, or None
363    /// if the key is not present in the map.
364    ///
365    /// The returned handle can be used to manipulate the position of the
366    /// entry within the map's iteration order without affecting the
367    /// iteration order of access methods like `get()`, `get_mut()`, etc.
368    ///
369    /// This method should complete in *O*(*1*) time.
370    ///
371    /// # Examples
372    /// ```
373    /// use deepmesa_collections::LinkedHashMap;
374    /// use deepmesa_collections::lhmap::Order;
375    ///
376    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
377    /// lhm.insert(1, "a");
378    /// lhm.insert(2, "b");
379    /// lhm.insert(3, "c");
380    ///
381    /// // Get handle for key 1
382    /// if let Some(handle) = lhm.entry_handle(&1) {
383    ///     // Move it to the end of iteration order
384    ///     lhm.make_tail(handle);
385    /// }
386    ///
387    /// // Now iteration order will be: 2, 3, 1
388    /// let keys: Vec<_> = lhm.keys().copied().collect();
389    /// assert_eq!(keys, vec![2, 3, 1]);
390    ///
391    /// // Non-existent key returns None
392    /// assert_eq!(lhm.entry_handle(&99), None);
393    /// ```
394    pub fn entry_handle(&self, key: &K) -> Option<EntryHandle<K, V>> {
395        if let Some(node_handle) = self.map.get(&PtrKey::new(key)) {
396            return Some(EntryHandle::new(node_handle.clone()));
397        }
398        None
399    }
400
401    /// Moves the entry associated with the given handle to the tail of the 
402    /// LinkedHashMap's iteration order (making it the most recently used).
403    ///
404    /// If the entry is already at the tail of the iteration order, this 
405    /// operation has no effect. This method works regardless of whether the
406    /// map uses InsertionOrder or AccessOrder.
407    ///
408    /// Returns `true` if the entry was successfully moved to the tail (or was
409    /// already at the tail), and `false` if the handle is invalid.
410    ///
411    /// This operation completes in O(1) time.
412    ///
413    /// # Examples
414    /// ```
415    /// use deepmesa_collections::LinkedHashMap;
416    /// use deepmesa_collections::lhmap::Order;
417    ///
418    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
419    /// lhm.put(1, "a");
420    /// lhm.put(2, "b");
421    /// lhm.put(3, "c");
422    ///
423    /// if let Some(handle) = lhm.entry_handle(&1) {
424    ///     assert!(lhm.make_tail(handle));
425    ///     
426    ///     // Now key 1 will be the last in iteration order
427    ///     let keys: Vec<_> = lhm.keys().copied().collect();
428    ///     assert_eq!(keys, vec![2, 3, 1]);
429    /// }
430    /// ```
431    pub fn make_tail(&mut self, eh: EntryHandle<K, V>) -> bool {
432        self.ll.make_tail(&eh.node_handle)
433    }
434
435    /// Moves the entry associated with the given handle to the head of the 
436    /// LinkedHashMap's iteration order (making it the least recently used).
437    ///
438    /// If the entry is already at the head of the iteration order, this 
439    /// operation has no effect. This method works regardless of whether the
440    /// map uses InsertionOrder or AccessOrder.
441    ///
442    /// Returns `true` if the entry was successfully moved to the head (or was
443    /// already at the head), and `false` if the handle is invalid.
444    ///
445    /// This operation completes in O(1) time.
446    ///
447    /// # Examples
448    /// ```
449    /// use deepmesa_collections::LinkedHashMap;
450    /// use deepmesa_collections::lhmap::Order;
451    ///
452    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
453    /// lhm.put(1, "a");
454    /// lhm.put(2, "b");
455    /// lhm.put(3, "c");
456    ///
457    /// if let Some(handle) = lhm.entry_handle(&3) {
458    ///     assert!(lhm.make_head(handle));
459    ///     
460    ///     // Now key 3 will be the first in iteration order
461    ///     let keys: Vec<_> = lhm.keys().copied().collect();
462    ///     assert_eq!(keys, vec![3, 1, 2]);
463    /// }
464    /// ```
465    pub fn make_head(&mut self, eh: EntryHandle<K, V>) -> bool {
466        self.ll.make_head(&eh.node_handle)
467    }
468
469    /// Returns a reference to the key-value pair associated with the given EntryHandle.
470    ///
471    /// This method provides O(1) access to an entry using its handle, without affecting
472    /// the iteration order (unlike [`get()`](#method.get) which may move accessed entries
473    /// to the tail in AccessOrder mode).
474    ///
475    /// Returns `Some((key, value))` if the handle is valid, or `None` if the handle
476    /// is invalid (e.g., the entry was removed from the map).
477    ///
478    /// This operation completes in O(1) time.
479    ///
480    /// # Examples
481    /// ```
482    /// use deepmesa_collections::LinkedHashMap;
483    /// use deepmesa_collections::lhmap::Order;
484    ///
485    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
486    /// lhm.put(1, "a");
487    /// lhm.put(2, "b");
488    /// lhm.put(3, "c");
489    ///
490    /// if let Some(handle) = lhm.entry_handle(&2) {
491    ///     // Get the entry without affecting iteration order
492    ///     assert_eq!(lhm.get_entry(&handle), Some((&2, &"b")));
493    ///     
494    ///     // Verify order is unchanged
495    ///     let keys: Vec<_> = lhm.keys().copied().collect();
496    ///     assert_eq!(keys, vec![1, 2, 3]);
497    /// }
498    ///
499    /// // Invalid handle returns None
500    /// let invalid_handle = deepmesa_collections::lhmap::EntryHandle::default();
501    /// assert_eq!(lhm.get_entry(&invalid_handle), None);
502    /// ```
503    pub fn get_entry(&self, handle: &EntryHandle<K, V>) -> Option<(&K, &V)> {
504        if let Some(entry) = handle.node_handle.val(&self.ll) {
505            Some((&entry.key, &entry.val))
506        } else {
507            None
508        }
509    }
510
511    /// Returns a reference to the key associated with the given EntryHandle.
512    ///
513    /// This method provides O(1) access to just the key of an entry using its handle, 
514    /// without affecting the iteration order. This is useful when you only need the key
515    /// and want to avoid destructuring the result of [`get_entry()`](#method.get_entry).
516    ///
517    /// Returns `Some(key)` if the handle is valid, or `None` if the handle
518    /// is invalid (e.g., the entry was removed from the map).
519    ///
520    /// This operation completes in O(1) time.
521    ///
522    /// # Examples
523    /// ```
524    /// use deepmesa_collections::LinkedHashMap;
525    /// use deepmesa_collections::lhmap::Order;
526    ///
527    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
528    /// lhm.put(1, "a");
529    /// lhm.put(2, "b");
530    /// lhm.put(3, "c");
531    ///
532    /// if let Some(handle) = lhm.entry_handle(&2) {
533    ///     // Get just the key without affecting iteration order
534    ///     assert_eq!(lhm.get_key(&handle), Some(&2));
535    ///     
536    ///     // Verify order is unchanged
537    ///     let keys: Vec<_> = lhm.keys().copied().collect();
538    ///     assert_eq!(keys, vec![1, 2, 3]);
539    /// }
540    ///
541    /// // Invalid handle returns None
542    /// let invalid_handle = deepmesa_collections::lhmap::EntryHandle::default();
543    /// assert_eq!(lhm.get_key(&invalid_handle), None);
544    /// ```
545    pub fn get_key(&self, handle: &EntryHandle<K, V>) -> Option<&K> {
546        handle.node_handle.val(&self.ll).map(|entry| &entry.key)
547    }
548
549    /// Returns a reference to the value associated with the given EntryHandle.
550    ///
551    /// This method provides O(1) access to just the value of an entry using its handle, 
552    /// without affecting the iteration order. This is useful when you only need the value
553    /// and want to avoid destructuring the result of [`get_entry()`](#method.get_entry).
554    ///
555    /// Returns `Some(value)` if the handle is valid, or `None` if the handle
556    /// is invalid (e.g., the entry was removed from the map).
557    ///
558    /// This operation completes in O(1) time.
559    ///
560    /// # Examples
561    /// ```
562    /// use deepmesa_collections::LinkedHashMap;
563    /// use deepmesa_collections::lhmap::Order;
564    ///
565    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
566    /// lhm.put(1, "a");
567    /// lhm.put(2, "b");
568    /// lhm.put(3, "c");
569    ///
570    /// if let Some(handle) = lhm.entry_handle(&2) {
571    ///     // Get just the value without affecting iteration order
572    ///     assert_eq!(lhm.get_value(&handle), Some(&"b"));
573    ///     
574    ///     // Verify order is unchanged
575    ///     let keys: Vec<_> = lhm.keys().copied().collect();
576    ///     assert_eq!(keys, vec![1, 2, 3]);
577    /// }
578    ///
579    /// // Invalid handle returns None
580    /// let invalid_handle = deepmesa_collections::lhmap::EntryHandle::default();
581    /// assert_eq!(lhm.get_value(&invalid_handle), None);
582    /// ```
583    pub fn get_value(&self, handle: &EntryHandle<K, V>) -> Option<&V> {
584        handle.node_handle.val(&self.ll).map(|entry| &entry.val)
585    }
586
587    /// Returns a mutable reference to the value associated with the given EntryHandle.
588    ///
589    /// This method provides O(1) mutable access to the value of an entry using its handle, 
590    /// without affecting the iteration order. This allows you to modify the value in-place
591    /// while preserving the entry's position in the map.
592    ///
593    /// Returns `Some(value)` if the handle is valid, or `None` if the handle
594    /// is invalid (e.g., the entry was removed from the map).
595    ///
596    /// This operation completes in O(1) time.
597    ///
598    /// # Examples
599    /// ```
600    /// use deepmesa_collections::LinkedHashMap;
601    /// use deepmesa_collections::lhmap::Order;
602    ///
603    /// let mut lhm = LinkedHashMap::<u16, String>::new(10, Order::InsertionOrder, None);
604    /// lhm.put(1, "a".to_string());
605    /// lhm.put(2, "b".to_string());
606    /// lhm.put(3, "c".to_string());
607    ///
608    /// if let Some(handle) = lhm.entry_handle(&2) {
609    ///     // Mutate the value without affecting iteration order
610    ///     if let Some(value) = lhm.get_value_mut(&handle) {
611    ///         value.push_str("_modified");
612    ///     }
613    ///     
614    ///     // Verify the change
615    ///     assert_eq!(lhm.get_value(&handle), Some(&"b_modified".to_string()));
616    ///     
617    ///     // Verify order is unchanged
618    ///     let keys: Vec<_> = lhm.keys().copied().collect();
619    ///     assert_eq!(keys, vec![1, 2, 3]);
620    /// }
621    ///
622    /// // Invalid handle returns None
623    /// let invalid_handle = deepmesa_collections::lhmap::EntryHandle::default();
624    /// assert_eq!(lhm.get_value_mut(&invalid_handle), None);
625    /// ```
626    pub fn get_value_mut(&mut self, handle: &EntryHandle<K, V>) -> Option<&mut V> {
627        handle.node_handle.val_mut(&mut self.ll).map(|entry| &mut entry.val)
628    }
629
630    /// Removes and returns the head (oldest) entry from the LinkedHashMap.
631    ///
632    /// The head entry is the least recently inserted or accessed entry depending 
633    /// on the map's order mode. This is the same entry that would be removed by 
634    /// the eviction policy.
635    ///
636    /// Returns `Some((key, value))` if an entry was removed, or `None` if the 
637    /// map is empty.
638    ///
639    /// This operation completes in O(1) time.
640    ///
641    /// # Examples
642    /// ```
643    /// use deepmesa_collections::LinkedHashMap;
644    /// use deepmesa_collections::lhmap::Order;
645    ///
646    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
647    /// lhm.put(1, "a");
648    /// lhm.put(2, "b");
649    /// lhm.put(3, "c");
650    ///
651    /// // Remove the head (oldest entry)
652    /// assert_eq!(lhm.remove_head(), Some((1, "a")));
653    /// assert_eq!(lhm.remove_head(), Some((2, "b")));
654    /// assert_eq!(lhm.remove_head(), Some((3, "c")));
655    /// assert_eq!(lhm.remove_head(), None);
656    /// ```
657    /// Returns a reference to the head (oldest) entry in the LinkedHashMap.
658    ///
659    /// The head entry is the least recently inserted or accessed entry depending
660    /// on the map's order mode. This is the entry that would be removed by the
661    /// eviction policy.
662    ///
663    /// Returns `Some((&key, &value))` if the map is not empty, or `None` if the
664    /// map is empty.
665    ///
666    /// This operation completes in O(1) time and does not modify the map.
667    ///
668    /// Returns a reference to the entry at the head of the LinkedHashMap.
669    ///
670    /// This method does not change the access order and works the same
671    /// regardless of whether the map uses InsertionOrder or AccessOrder.
672    /// Unlike insertion operations, this method is purely a read operation
673    /// and will not affect the ordering of entries.
674    ///
675    /// # Examples
676    /// ```
677    /// use deepmesa_collections::LinkedHashMap;
678    /// use deepmesa_collections::lhmap::Order;
679    ///
680    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
681    /// assert_eq!(lhm.head(), None);
682    ///
683    /// lhm.put(1, "a");
684    /// lhm.put(2, "b");
685    /// lhm.put(3, "c");
686    ///
687    /// // Head is the oldest entry
688    /// assert_eq!(lhm.head(), Some((&1, &"a")));
689    /// ```
690    pub fn head(&self) -> Option<(&K, &V)> {
691        if let Some(entry) = self.ll.head() {
692            Some((&entry.key, &entry.val))
693        } else {
694            None
695        }
696    }
697
698    pub fn remove_head(&mut self) -> Option<(K, V)> {
699        if let Some(entry) = self.ll.pop_head() {
700            self.map.remove(&PtrKey::new(&entry.key));
701            Some((entry.key, entry.val))
702        } else {
703            None
704        }
705    }
706
707    /// Removes and returns the tail (newest) entry from the LinkedHashMap.
708    ///
709    /// The tail entry is the most recently inserted or accessed entry depending 
710    /// on the map's order mode. This is the opposite of the entry that would be 
711    /// removed by the eviction policy.
712    ///
713    /// Returns `Some((key, value))` if an entry was removed, or `None` if the 
714    /// map is empty.
715    ///
716    /// This operation completes in O(1) time.
717    ///
718    /// # Examples
719    /// ```
720    /// use deepmesa_collections::LinkedHashMap;
721    /// use deepmesa_collections::lhmap::Order;
722    ///
723    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
724    /// lhm.put(1, "a");
725    /// lhm.put(2, "b");
726    /// lhm.put(3, "c");
727    ///
728    /// // Remove the tail (newest entry)
729    /// assert_eq!(lhm.remove_tail(), Some((3, "c")));
730    /// assert_eq!(lhm.remove_tail(), Some((2, "b")));
731    /// assert_eq!(lhm.remove_tail(), Some((1, "a")));
732    /// assert_eq!(lhm.remove_tail(), None);
733    /// ```
734    /// Returns a reference to the tail (newest) entry in the LinkedHashMap.
735    ///
736    /// The tail entry is the most recently inserted or accessed entry depending
737    /// on the map's order mode. This is the opposite of the entry that would be
738    /// removed by the eviction policy.
739    ///
740    /// Returns `Some((&key, &value))` if the map is not empty, or `None` if the
741    /// map is empty.
742    ///
743    /// This operation completes in O(1) time and does not modify the map.
744    ///
745    /// Returns a reference to the entry at the tail of the LinkedHashMap.
746    ///
747    /// This method does not change the access order and works the same
748    /// regardless of whether the map uses InsertionOrder or AccessOrder.
749    /// Unlike insertion operations, this method is purely a read operation
750    /// and will not affect the ordering of entries.
751    ///
752    /// # Examples
753    /// ```
754    /// use deepmesa_collections::LinkedHashMap;
755    /// use deepmesa_collections::lhmap::Order;
756    ///
757    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
758    /// assert_eq!(lhm.tail(), None);
759    ///
760    /// lhm.put(1, "a");
761    /// lhm.put(2, "b");
762    /// lhm.put(3, "c");
763    ///
764    /// // Tail is the newest entry
765    /// assert_eq!(lhm.tail(), Some((&3, &"c")));
766    /// ```
767    pub fn tail(&self) -> Option<(&K, &V)> {
768        if let Some(entry) = self.ll.tail() {
769            Some((&entry.key, &entry.val))
770        } else {
771            None
772        }
773    }
774
775    pub fn remove_tail(&mut self) -> Option<(K, V)> {
776        if let Some(entry) = self.ll.pop_tail() {
777            self.map.remove(&PtrKey::new(&entry.key));
778            Some((entry.key, entry.val))
779        } else {
780            None
781        }
782    }
783
784    /// Returns a reference to the value corresponding to the key. If
785    /// the Map was created with AccessOrder then the key accessed is
786    /// moved to the tail of the underlying linked list (most
787    /// recently used).
788    ///
789    /// If the key is not present then this method returns None and
790    /// the order is unaffected.
791    ///
792    /// # Examples
793    ///
794    /// ```
795    /// use deepmesa_collections::LinkedHashMap;
796    /// use deepmesa_collections::lhmap::Order;
797    ///
798    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
799    /// lhm.insert(1, "a");
800    /// lhm.insert(2, "b");
801    ///
802    /// let mut iter = lhm.iter();
803    /// assert_eq!(iter.next(), Some((&1, &"a")));
804    /// assert_eq!(iter.next(), Some((&2, &"b")));
805    ///
806    /// assert_eq!(lhm.get(&1), Some(&"a"));
807    /// assert_eq!(lhm.get(&3), None);
808    ///
809    /// let mut iter = lhm.iter();
810    /// assert_eq!(iter.next(), Some((&2, &"b")));
811    /// assert_eq!(iter.next(), Some((&1, &"a")));
812    /// assert_eq!(iter.next(), None);
813    ///
814    /// ```
815    pub fn get(&mut self, key: &K) -> Option<&V> {
816        if let Some(llnode) = self.map.get(&PtrKey::new(key)) {
817            if self.order == Order::AccessOrder {
818                if !self.ll.make_tail(llnode) {
819                    panic!("failed to make tail!");
820                }
821            }
822
823            match llnode.val(&self.ll) {
824                None => panic!("List does not doesn't contain expected value!"),
825                Some(entry) => {
826                    return Some(&entry.val);
827                }
828            }
829        }
830        None
831    }
832
833    /// Returns the key-value pair corresponding to the supplied key.
834    /// the Map was created with AccessOrder then the key accessed is
835    /// moved to the tail of the underlying linked list (most
836    /// recently accessed).
837    ///
838    /// If the key is not present then this method returns None and
839    /// the order is unaffected.
840    ///
841    /// # Examples
842    /// ```
843    /// use deepmesa_collections::LinkedHashMap;
844    /// use deepmesa_collections::lhmap::Order;
845    ///
846    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
847    /// lhm.insert(1, "a");
848    /// lhm.insert(2, "b");
849    ///
850    /// let mut iter = lhm.iter();
851    /// assert_eq!(iter.next(), Some((&1, &"a")));
852    /// assert_eq!(iter.next(), Some((&2, &"b")));
853    ///
854    /// assert_eq!(lhm.get_key_value(&1), Some((&1, &"a")));
855    /// assert_eq!(lhm.get(&3), None);
856    ///
857    /// let mut iter = lhm.iter();
858    /// assert_eq!(iter.next(), Some((&2, &"b")));
859    /// assert_eq!(iter.next(), Some((&1, &"a")));
860    /// assert_eq!(iter.next(), None);
861    ///
862    /// ```
863    pub fn get_key_value(&mut self, key: &K) -> Option<(&K, &V)> {
864        if let Some(llnode) = self.map.get(&PtrKey::new(key)) {
865            if self.order == Order::AccessOrder {
866                if !self.ll.make_tail(llnode) {
867                    panic!("failed to make tail!");
868                }
869            }
870
871            match llnode.val(&self.ll) {
872                None => panic!("List does not doesn't contain expected value!"),
873                Some(entry) => {
874                    return Some((&entry.key, &entry.val));
875                }
876            }
877        }
878        None
879    }
880
881    /// Returns a mutable reference to the value corresponding to the key. If
882    /// the Map was created with AccessOrder then the key accessed is
883    /// moved to the tail of the underlying linked list (most
884    /// recently used).
885    ///
886    /// If the key is not present then this method returns None and
887    /// the order is unaffected.
888    ///
889    /// # Examples
890    ///
891    /// ```
892    /// use deepmesa_collections::LinkedHashMap;
893    /// use deepmesa_collections::lhmap::Order;
894    ///
895    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
896    /// lhm.insert(1, "a");
897    /// lhm.insert(2, "b");
898    ///
899    /// let mut iter = lhm.iter();
900    /// assert_eq!(iter.next(), Some((&1, &"a")));
901    /// assert_eq!(iter.next(), Some((&2, &"b")));
902    ///
903    /// if let Some(val) = lhm.get_mut(&1) {
904    ///     *val = "d";
905    /// }
906    ///
907    /// let mut iter = lhm.iter();
908    /// assert_eq!(iter.next(), Some((&2, &"b")));
909    /// assert_eq!(iter.next(), Some((&1, &"d")));
910    /// assert_eq!(iter.next(), None);
911    ///
912    /// ```
913    pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
914        if let Some(llnode) = self.map.get(&PtrKey::new(key)) {
915            if self.order == Order::AccessOrder {
916                if !self.ll.make_tail(llnode) {
917                    panic!("failed to make tail!");
918                }
919            }
920
921            match llnode.val_mut(&mut self.ll) {
922                None => panic!("List does not doesn't contain expected value!"),
923                Some(entry) => {
924                    return Some(&mut entry.val);
925                }
926            }
927        }
928        None
929    }
930
931    /// Removes a key from the map, returning the value at the key if
932    /// the key was previously in the map. If the key was not present
933    /// then this method returns None. The iteration order is not
934    /// affected by this method except to remove the specified key
935    /// from the underlying linked list.
936    ///
937    /// # Examples
938    ///
939    /// ```
940    /// use deepmesa_collections::LinkedHashMap;
941    /// use deepmesa_collections::lhmap::Order;
942    ///
943    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
944    /// lhm.insert(1, "a");
945    /// assert_eq!(lhm.remove(&1), Some("a"));
946    /// assert_eq!(lhm.remove(&1), None);
947    /// ```
948    pub fn remove(&mut self, key: &K) -> Option<V> {
949        if let Some(llnode) = self.map.remove(&PtrKey::new(key)) {
950            match self.ll.pop_node(&llnode) {
951                None => panic!("List doesn't contain expected value!"),
952                Some(entry) => return Some(entry.val),
953            }
954        }
955
956        None
957    }
958
959    /// Removes a key from the map, returning the key value pair at
960    /// the key if the key was previously in the map. If the key was
961    /// not present then this method returns None. The iteration order
962    /// is not affected by this method except to remove the specified
963    /// key from the underlying linked list.
964    ///
965    /// # Examples
966    ///
967    /// ```
968    /// use deepmesa_collections::LinkedHashMap;
969    /// use deepmesa_collections::lhmap::Order;
970    ///
971    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
972    /// lhm.insert(1, "a");
973    /// assert_eq!(lhm.remove_entry(&1), Some((1, "a")));
974    /// assert_eq!(lhm.remove(&1), None);
975    /// ```
976    pub fn remove_entry(&mut self, key: &K) -> Option<(K, V)> {
977        if let Some(llnode) = self.map.remove(&PtrKey::new(key)) {
978            match self.ll.pop_node(&llnode) {
979                None => panic!("List doesn't contain expected value!"),
980                Some(entry) => return Some((entry.key, entry.val)),
981            }
982        }
983
984        None
985    }
986
987    /// Inserts a key-value pair into the map. Unlike the insert
988    /// method this does not return the old value previously stored.
989    /// The new value inserted is placed at the tail of the underlying
990    /// linked list (most recently used).
991    ///
992    /// #Examples
993    /// ```
994    /// use deepmesa_collections::LinkedHashMap;
995    /// use deepmesa_collections::lhmap::Order;
996    ///
997    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
998    /// lhm.put(1, "a");
999    /// assert_eq!(lhm.is_empty(), false);
1000    /// ```
1001    pub fn put(&mut self, k: K, v: V) {
1002        match self.map.get(&PtrKey::new(&k)) {
1003            Some(llnode) => match llnode.val_mut(&mut self.ll) {
1004                None => panic!("Value not found in LL"),
1005                Some(entry) => {
1006                    (*entry).val = v;
1007                    if !self.ll.make_tail(llnode) {
1008                        panic!("failed to make tail!");
1009                    }
1010                }
1011            },
1012            None => {
1013                let ll_node = self.ll.push_tail(Entry::new(k, v));
1014
1015                match self.ll.node(&ll_node) {
1016                    None => panic!("Value not found in LL"),
1017                    Some(entry_ref) => unsafe {
1018                        let key_ptr = entry_ref.key_ptr();
1019                        self.map.insert(PtrKey::from_ptr(key_ptr), ll_node);
1020                    },
1021                }
1022            }
1023        }
1024
1025        self.evict_eldest();
1026    }
1027
1028    /// Inserts a key-value pair into the map and returns the old
1029    /// value (if any). If a value was not present for this key then
1030    /// this method returns None.  The new value inserted is placed at
1031    /// the tail of the underlying linked list (most recently used).
1032    ///
1033    /// The key is not updated and only the value corresponding to the
1034    /// key is updated.
1035    ///
1036    /// #Examples
1037    /// ```
1038    /// use deepmesa_collections::LinkedHashMap;
1039    /// use deepmesa_collections::lhmap::Order;
1040    ///
1041    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
1042    /// assert_eq!(lhm.insert(1, "a"), None);
1043    /// assert_eq!(lhm.is_empty(), false);
1044    ///
1045    /// lhm.insert(2, "b");
1046    /// assert_eq!(lhm.insert(2, "c"), Some("b"));
1047    /// ```
1048    pub fn insert(&mut self, k: K, v: V) -> Option<V> {
1049        let mut retval: Option<V> = None;
1050
1051        match self.map.get(&PtrKey::new(&k)) {
1052            None => {
1053                let ll_node = self.ll.push_tail(Entry::new(k, v));
1054
1055                match self.ll.node(&ll_node) {
1056                    None => panic!("Value not found in LL"),
1057                    Some(entry_ref) => unsafe {
1058                        let key_ptr = entry_ref.key_ptr();
1059                        self.map.insert(PtrKey::from_ptr(key_ptr), ll_node);
1060                    },
1061                }
1062            }
1063            Some(llnode) => match llnode.val_mut(&mut self.ll) {
1064                None => panic!("value not found in linkedlist"),
1065                Some(entry) => {
1066                    retval = Some(std::mem::replace(&mut (*entry).val, v));
1067                    if !self.ll.make_tail(llnode) {
1068                        panic!("failed to make tail!");
1069                    }
1070                }
1071            },
1072        }
1073
1074        self.evict_eldest();
1075        return retval;
1076    }
1077
1078    /// An Iterator that vists all key value pairs in a predictable
1079    /// order.
1080    ///
1081    /// Iteration over the map requires time proportional to the
1082    /// length of the map (*O*(*len*)) regardless of the capacity
1083    /// because it iterates over the elements of the underlying linked
1084    /// list. If the map is constructed with [`InsertionOrder`](Order)
1085    /// then the iteration order is from oldest entry inserted to the
1086    /// newest entry inserted. If the map is constructed with
1087    /// [`AccessOrder`](Order) then the iteration order is from oldest
1088    /// entry accessed to the newest entry accessed.
1089    ///
1090    /// The iterator element type is (&'a K, &'a V).
1091    ///
1092    /// # Examples
1093    /// ```
1094    /// use deepmesa_collections::LinkedHashMap;
1095    /// use deepmesa_collections::lhmap::Order;
1096    ///
1097    /// // Construct a map in InsertionOrder
1098    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
1099    /// lhm.put(1, "a");
1100    /// lhm.put(2, "b");
1101    ///
1102    /// lhm.get(&1);
1103    ///
1104    /// let mut iter = lhm.iter();
1105    /// assert_eq!(iter.next(), Some((&1, &"a")));
1106    /// assert_eq!(iter.next(), Some((&2, &"b")));
1107    ///
1108    /// // Construct a map in AccessOrder
1109    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
1110    /// lhm.put(1, "a");
1111    /// lhm.put(2, "b");
1112    ///
1113    /// lhm.get(&1);
1114    ///
1115    /// let mut iter = lhm.iter();
1116    /// assert_eq!(iter.next(), Some((&2, &"b")));
1117    /// assert_eq!(iter.next(), Some((&1, &"a")));
1118    /// ```
1119    pub fn iter(&self) -> Iter<'_, K, V> {
1120        return Iter::new(self);
1121    }
1122
1123    /// An Iterator that vists all key value pairs in a predictable
1124    /// order with mutable references to the values.
1125    ///
1126    /// Iteration over the map requires time proportional to the
1127    /// length of the map (*O*(*len*)) regardless of the capacity
1128    /// because it iterates over the elements of the underlying linked
1129    /// list. If the map is constructed with [`InsertionOrder`](Order)
1130    /// then the iteration order is from oldest entry inserted to the
1131    /// newest entry inserted. If the map is constructed with
1132    /// [`AccessOrder`](Order) then the iteration order is from oldest
1133    /// entry accessed to the newest entry accessed
1134    ///
1135    /// The iterator element type is (&'a K, &'a mut V).
1136    ///
1137    /// # Examples
1138    /// ```
1139    /// use deepmesa_collections::LinkedHashMap;
1140    /// use deepmesa_collections::lhmap::Order;
1141    ///
1142    /// // Construct a map in InsertionOrder
1143    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
1144    /// lhm.put(1, "a");
1145    /// lhm.put(2, "b");
1146    ///
1147    /// lhm.get(&1);
1148    ///
1149    /// for (_, val) in lhm.iter_mut() {
1150    ///     *val = "d";
1151    /// }
1152    ///
1153    /// assert_eq!(lhm.get(&1), Some(&"d"));
1154    /// assert_eq!(lhm.get(&2), Some(&"d"));
1155    ///
1156    /// ```
1157    pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
1158        return IterMut::new(self);
1159    }
1160
1161    /// An Iterator that vists all keys in a predictable order.
1162    ///
1163    /// Iteration over the map requires time proportional to the
1164    /// length of the map (*O*(*len*)) regardless of the capacity
1165    /// because it iterates over the elements of the underlying linked
1166    /// list. If the map is constructed with [`InsertionOrder`](Order)
1167    /// then the iteration order is from oldest entry inserted to the
1168    /// newest entry inserted. If the map is constructed with
1169    /// [`AccessOrder`](Order) then the iteration order is from oldest
1170    /// entry accessed to the newest entry accessed.
1171    ///
1172    /// The iterator element type is &'a K.
1173    ///
1174    /// # Examples
1175    /// ```
1176    /// use deepmesa_collections::LinkedHashMap;
1177    /// use deepmesa_collections::lhmap::Order;
1178    ///
1179    /// // Construct a map in InsertionOrder
1180    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
1181    /// lhm.put(1, "a");
1182    /// lhm.put(2, "b");
1183    ///
1184    /// lhm.get(&1);
1185    ///
1186    /// let mut iter = lhm.keys();
1187    /// assert_eq!(iter.next(), Some((&1)));
1188    /// assert_eq!(iter.next(), Some((&2)));
1189    ///
1190    /// // Construct a map in AccessOrder
1191    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
1192    /// lhm.put(1, "a");
1193    /// lhm.put(2, "b");
1194    ///
1195    /// lhm.get(&1);
1196    ///
1197    /// let mut iter = lhm.keys();
1198    /// assert_eq!(iter.next(), Some((&2)));
1199    /// assert_eq!(iter.next(), Some((&1)));
1200    /// ```
1201    pub fn keys(&self) -> Keys<'_, K, V> {
1202        return Keys::new(self);
1203    }
1204
1205    /// An Iterator that vists all values in a predictable order.
1206    ///
1207    /// Iteration over the map requires time proportional to the
1208    /// length of the map (*O*(*len*)) regardless of the capacity
1209    /// because it iterates over the elements of the underlying linked
1210    /// list. If the map is constructed with [`InsertionOrder`](Order)
1211    /// then the iteration order is from oldest entry inserted to the
1212    /// newest entry inserted. If the map is constructed with
1213    /// [`AccessOrder`](Order) then the iteration order is from oldest
1214    /// entry accessed to the newest entry accessed.
1215    ///
1216    /// The iterator element type is &'a V.
1217    ///
1218    /// # Examples
1219    /// ```
1220    /// use deepmesa_collections::LinkedHashMap;
1221    /// use deepmesa_collections::lhmap::Order;
1222
1223    ///
1224    /// // Construct a map in InsertionOrder
1225    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
1226    /// lhm.put(1, "a");
1227    /// lhm.put(2, "b");
1228    ///
1229    /// lhm.get(&1);
1230    ///
1231    /// let mut iter = lhm.values();
1232    /// assert_eq!(iter.next(), Some((&"a")));
1233    /// assert_eq!(iter.next(), Some((&"b")));
1234    ///
1235    /// // Construct a map in AccessOrder
1236    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
1237    /// lhm.put(1, "a");
1238    /// lhm.put(2, "b");
1239    ///
1240    /// lhm.get(&1);
1241    ///
1242    /// let mut iter = lhm.values();
1243    /// assert_eq!(iter.next(), Some((&"b")));
1244    /// assert_eq!(iter.next(), Some((&"a")));
1245    /// ```
1246    pub fn values(&self) -> Values<'_, K, V> {
1247        return Values::new(self);
1248    }
1249
1250    /// An Iterator that vists all values in a predictable order with
1251    /// mutable references to the values.
1252    ///
1253    /// Iteration over the map requires time proportional to the
1254    /// length of the map (*O*(*len*)) regardless of the capacity
1255    /// because it iterates over the elements of the underlying linked
1256    /// list. If the map is constructed with [`InsertionOrder`](Order)
1257    /// then the iteration order is from oldest entry inserted to the
1258    /// newest entry inserted. If the map is constructed with
1259    /// [`AccessOrder`](Order) then the iteration order is from oldest
1260    /// entry accessed to the newest entry accessed.
1261    ///
1262    /// The iterator element type is &'a mut V.
1263    ///
1264    /// # Examples
1265    /// ```
1266    /// use deepmesa_collections::LinkedHashMap;
1267    /// use deepmesa_collections::lhmap::Order;
1268    ///
1269    /// // Construct a map in InsertionOrder
1270    /// let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
1271    /// lhm.put(1, "a");
1272    /// lhm.put(2, "b");
1273    ///
1274    /// lhm.get(&1);
1275    ///
1276    /// for val in lhm.values_mut() {
1277    ///     *val = "d";
1278    /// }
1279    ///
1280    /// assert_eq!(lhm.get(&1), Some(&"d"));
1281    /// assert_eq!(lhm.get(&2), Some(&"d"));
1282    ///
1283    /// ```
1284    pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
1285        return ValuesMut::new(self);
1286    }
1287
1288    fn evict_eldest(&mut self) {
1289        if let Some(ee_fn) = self.evict_eldest {
1290            if let Some(entry) = self.ll.head() {
1291                if ee_fn(self.len(), self.cap, entry) {
1292                    match self.ll.pop_head() {
1293                        None => panic!("pop head unexpectedly returned None"),
1294                        Some(entry) => {
1295                            self.map.remove(&PtrKey::new(&entry.key));
1296                        }
1297                    }
1298                }
1299            }
1300        }
1301    }
1302}
1303
1304#[cfg(test)]
1305mod tests {
1306    use super::Order;
1307    use crate::lhmap::entry::Entry;
1308    use crate::lhmap::lhmap::LinkedHashMap;
1309
1310    #[derive(Debug)]
1311    struct ValObject {
1312        int_v: u16,
1313    }
1314
1315    impl ValObject {
1316        fn new(val: u16) -> ValObject {
1317            return ValObject { int_v: val };
1318        }
1319    }
1320
1321    #[test]
1322    fn test_iter() {
1323        let mut lhm: LinkedHashMap<String, ValObject> =
1324            LinkedHashMap::new(10, Order::AccessOrder, None);
1325
1326        for i in 0u16..10 {
1327            lhm.put(format!("Hello-{}", i), ValObject::new(i));
1328            assert_eq!((i + 1) as usize, lhm.len());
1329        }
1330
1331        lhm.get(&"Hello-3".to_string());
1332
1333        let mut iter = lhm.iter();
1334        while let Some((key, val)) = iter.next() {
1335            println!("Key: {:?}, Val: {:?}", key, val);
1336        }
1337
1338        println!("Now using IntoIterator!");
1339
1340        for (key, val) in lhm.iter() {
1341            println!("Key: {:?}, Val: {:?}", key, val);
1342        }
1343
1344        println!("Now using Keys!");
1345
1346        let mut keys = lhm.keys();
1347        while let Some(key) = keys.next() {
1348            println!("Key: {:?}", key);
1349        }
1350
1351        println!("Now using Values!");
1352
1353        let mut values = lhm.values();
1354        while let Some(val) = values.next() {
1355            println!("Value: {:?}", val);
1356        }
1357    }
1358
1359    #[test]
1360    fn test_put_get_remove() {
1361        let mut lhm: LinkedHashMap<String, ValObject> =
1362            LinkedHashMap::new(10, Order::AccessOrder, None);
1363
1364        for i in 0u16..10 {
1365            lhm.put(format!("Hello-{}", i), ValObject::new(i));
1366            assert_eq!((i + 1) as usize, lhm.len());
1367        }
1368
1369        for i in 0u16..10 {
1370            match lhm.get(&format!("Hello-{}", i)) {
1371                None => {
1372                    assert!(false, "Unexpected None for Key Hello-{}", i);
1373                    assert_eq!(10, lhm.len());
1374                }
1375                Some(val_o) => {
1376                    assert_eq!(val_o.int_v, i);
1377                }
1378            }
1379        }
1380
1381        for i in 0u16..10 {
1382            match lhm.remove(&format!("Hello-{}", i)) {
1383                None => {
1384                    assert!(false, "Unexpected None for removed Key Hello-{}", i);
1385                }
1386                Some(val_o) => {
1387                    assert_eq!(val_o.int_v, i);
1388                }
1389            }
1390
1391            match lhm.get(&format!("Hello-{}", i)) {
1392                None => {
1393                    assert!(true);
1394                }
1395                Some(val_o) => {
1396                    assert!(false, "Unexpected Some with val: {}", val_o.int_v);
1397                }
1398            }
1399        }
1400    }
1401
1402    #[test]
1403    fn test_put_overwrite() {
1404        let mut lhm: LinkedHashMap<String, ValObject> =
1405            LinkedHashMap::new(10, Order::AccessOrder, None);
1406        lhm.put("Hello-0".to_string(), ValObject::new(0));
1407        assert_eq!(lhm.len(), 1);
1408
1409        match lhm.get(&"Hello-0".to_string()) {
1410            None => {
1411                assert!(false, "Unexpected None for Key Hello-0");
1412            }
1413            Some(val_o) => {
1414                assert_eq!(val_o.int_v, 0);
1415                assert_eq!(lhm.len(), 1);
1416            }
1417        }
1418
1419        lhm.put("Hello-0".to_string(), ValObject::new(10));
1420        match lhm.get(&"Hello-0".to_string()) {
1421            None => {
1422                assert!(false, "Unexpected None for Key Hello-0");
1423            }
1424            Some(val_o) => {
1425                assert_eq!(val_o.int_v, 10);
1426                assert_eq!(lhm.len(), 1);
1427            }
1428        }
1429    }
1430
1431    fn evict_fn<K, V>(len: usize, capacity: usize, _e: &Entry<K, V>) -> bool {
1432        if len > capacity {
1433            return true;
1434        }
1435        return false;
1436    }
1437
1438    #[test]
1439    fn test_eviction() {
1440        let mut lhm: LinkedHashMap<String, ValObject> =
1441            LinkedHashMap::new(10, Order::AccessOrder, Some(evict_fn));
1442
1443        for i in 0u16..20 {
1444            lhm.put(format!("Hello-{}", i), ValObject::new(i));
1445            if i >= 10 {
1446                assert_eq!(10, lhm.len());
1447            } else {
1448                assert_eq!((i + 1) as usize, lhm.len());
1449            }
1450        }
1451    }
1452
1453    #[test]
1454    fn test_foo() {
1455        use crate::lhmap::entry::Entry;
1456        pub fn evict<K, V>(len: usize, capacity: usize, _e: &Entry<K, V>) -> bool {
1457            if len > capacity {
1458                return true;
1459            }
1460            return false;
1461        }
1462
1463        use crate::lhmap::entry::Order;
1464        use crate::lhmap::lhmap::LinkedHashMap;
1465
1466        let mut lhm = LinkedHashMap::<u16, &str>::new(2, Order::AccessOrder, Some(evict));
1467        lhm.put(1, "a");
1468        lhm.put(2, "b");
1469        lhm.put(3, "c");
1470
1471        assert_eq!(lhm.get(&2), Some(&"b"));
1472        lhm.put(4, "d");
1473        assert_eq!(lhm.get(&1), None);
1474
1475        // let mut lhm = LinkedHashMap::<&str, u16>::with_capacity(10);
1476        // lhm.put("a", 1);
1477        // lhm.put("b", 2);
1478        // lhm.put("c", 3);
1479        // lhm.put("d", 4);
1480
1481        // let mut iter = lhm.iter();
1482        // println!("{:?}", iter.next());
1483        // println!("{:?}", iter.next());
1484        // println!("{:?}", iter.next());
1485        // println!("{:?}", iter.next());
1486        // println!("{:?}", iter.next());
1487        // println!("{:?}", iter.next());
1488        // println!("Now in reverse!");
1489        // iter = iter.reverse();
1490        // println!("{:?}", iter.next());
1491        // println!("{:?}", iter.next());
1492
1493        // println!("Now in reverse!");
1494
1495        // //assert_eq!(lhm.get(&"a"), Some(&1));
1496        // let mut iter = lhm.iter().reverse();
1497        // println!("{:?}", iter.next());
1498        // println!("{:?}", iter.next());
1499        // println!("{:?}", iter.next());
1500    }
1501
1502    #[test]
1503    fn test_entry_handle_basic() {
1504        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
1505        lhm.put(1, "a");
1506        lhm.put(2, "b");
1507        lhm.put(3, "c");
1508
1509        // Test getting valid handle
1510        let handle1 = lhm.entry_handle(&1);
1511        assert!(handle1.is_some());
1512        
1513        // Test getting invalid handle
1514        let handle_invalid = lhm.entry_handle(&99);
1515        assert!(handle_invalid.is_none());
1516    }
1517
1518
1519    #[test]
1520    fn test_entry_handle_make_tail_insertion_order() {
1521        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
1522        lhm.put(1, "a");
1523        lhm.put(2, "b");
1524        lhm.put(3, "c");
1525
1526        // Initial order should be 1, 2, 3
1527        let keys: Vec<_> = lhm.keys().copied().collect();
1528        assert_eq!(keys, vec![1, 2, 3]);
1529
1530        // Move key 1 to end
1531        if let Some(handle) = lhm.entry_handle(&1) {
1532            assert!(lhm.make_tail(handle));
1533        }
1534
1535        // Order should now be 2, 3, 1
1536        let keys: Vec<_> = lhm.keys().copied().collect();
1537        assert_eq!(keys, vec![2, 3, 1]);
1538
1539        // Values should remain unchanged (use mutable reference for get)
1540        assert_eq!(lhm.get(&1), Some(&"a"));
1541        assert_eq!(lhm.get(&2), Some(&"b"));
1542        assert_eq!(lhm.get(&3), Some(&"c"));
1543    }
1544
1545    #[test]
1546    fn test_entry_handle_make_tail_access_order() {
1547        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
1548        lhm.put(1, "a");
1549        lhm.put(2, "b");
1550        lhm.put(3, "c");
1551
1552        // Initial order should be 1, 2, 3 (insertion order)
1553        let keys: Vec<_> = lhm.keys().copied().collect();
1554        assert_eq!(keys, vec![1, 2, 3]);
1555
1556        // Move key 1 to end using handle (should work regardless of AccessOrder)
1557        if let Some(handle) = lhm.entry_handle(&1) {
1558            assert!(lhm.make_tail(handle));
1559        }
1560
1561        // Order should now be 2, 3, 1
1562        let keys: Vec<_> = lhm.keys().copied().collect();
1563        assert_eq!(keys, vec![2, 3, 1]);
1564    }
1565
1566    #[test]
1567    fn test_entry_handle_make_tail_already_at_end() {
1568        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
1569        lhm.put(1, "a");
1570        lhm.put(2, "b");
1571        lhm.put(3, "c");
1572
1573        // Move key 3 to end first to make it actually at the end
1574        if let Some(handle) = lhm.entry_handle(&3) {
1575            assert!(lhm.make_tail(handle));
1576        }
1577        
1578        // Now 3 should be at the end: [1, 2, 3]
1579        let keys: Vec<_> = lhm.keys().copied().collect();
1580        assert_eq!(keys, vec![1, 2, 3]);
1581
1582        // Move key 3 to end again (it's already at the end)
1583        if let Some(handle) = lhm.entry_handle(&3) {
1584            assert!(lhm.make_tail(handle));
1585        }
1586
1587        // Order should remain the same: 1, 2, 3
1588        let keys: Vec<_> = lhm.keys().copied().collect();
1589        assert_eq!(keys, vec![1, 2, 3]);
1590    }
1591
1592    #[test]
1593    fn test_entry_handle_invalid_handle() {
1594        let mut lhm1 = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
1595        let mut lhm2 = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
1596        
1597        lhm1.put(1, "a");
1598        lhm2.put(1, "b");
1599
1600        // Get handle from lhm1
1601        let handle = lhm1.entry_handle(&1).unwrap();
1602        
1603        // Remove the entry from lhm1 to invalidate the handle
1604        lhm1.remove(&1);
1605        
1606        // Try to use invalid handle - should return false
1607        assert_eq!(lhm1.make_tail(handle), false);
1608    }
1609
1610    #[test]
1611    fn test_entry_handle_multiple_operations() {
1612        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
1613        lhm.put(1, "a");
1614        lhm.put(2, "b");
1615        lhm.put(3, "c");
1616        lhm.put(4, "d");
1617
1618        // Initial order: [1, 2, 3, 4]
1619        let keys: Vec<_> = lhm.keys().copied().collect();
1620        assert_eq!(keys, vec![1, 2, 3, 4]);
1621
1622        // Move key 2 to end: [1, 3, 4, 2]
1623        if let Some(handle) = lhm.entry_handle(&2) {
1624            assert!(lhm.make_tail(handle));
1625        }
1626        let keys: Vec<_> = lhm.keys().copied().collect();
1627        assert_eq!(keys, vec![1, 3, 4, 2]);
1628
1629        // Move key 1 to end: [3, 4, 2, 1]
1630        if let Some(handle) = lhm.entry_handle(&1) {
1631            assert!(lhm.make_tail(handle));
1632        }
1633        let keys: Vec<_> = lhm.keys().copied().collect();
1634        assert_eq!(keys, vec![3, 4, 2, 1]);
1635    }
1636
1637    #[test]
1638    fn test_entry_handle_with_access_operations() {
1639        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
1640        lhm.put(1, "a");
1641        lhm.put(2, "b");
1642        lhm.put(3, "c");
1643
1644        // Initial order: [1, 2, 3]
1645        let keys: Vec<_> = lhm.keys().copied().collect();
1646        assert_eq!(keys, vec![1, 2, 3]);
1647
1648        // Access key 1 (should move it to head in AccessOrder, making it last in iteration)
1649        lhm.get(&1);
1650        let keys: Vec<_> = lhm.keys().copied().collect();
1651        assert_eq!(keys, vec![2, 3, 1]); // 1 moved to most recently accessed (end)
1652
1653        // Use handle to move key 2 to end (should move it to head of list, end of iteration)
1654        if let Some(handle) = lhm.entry_handle(&2) {
1655            assert!(lhm.make_tail(handle));
1656        }
1657        let keys: Vec<_> = lhm.keys().copied().collect();
1658        assert_eq!(keys, vec![3, 1, 2]); // 2 moved to end
1659    }
1660
1661    #[test]
1662    fn test_entry_handle_default() {
1663        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
1664        lhm.put(1, "a");
1665
1666        // Create a default handle (invalid)
1667        let default_handle = crate::lhmap::entry::EntryHandle::<u16, &str>::default();
1668        
1669        // Try to use it - should return false
1670        assert_eq!(lhm.make_tail(default_handle), false);
1671    }
1672
1673    #[test]
1674    fn test_get_entry_basic() {
1675        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
1676        lhm.put(1, "a");
1677        lhm.put(2, "b");
1678        lhm.put(3, "c");
1679
1680        // Test getting valid entries
1681        if let Some(handle1) = lhm.entry_handle(&1) {
1682            assert_eq!(lhm.get_entry(&handle1), Some((&1, &"a")));
1683        } else {
1684            panic!("Expected valid handle for key 1");
1685        }
1686
1687        if let Some(handle2) = lhm.entry_handle(&2) {
1688            assert_eq!(lhm.get_entry(&handle2), Some((&2, &"b")));
1689        } else {
1690            panic!("Expected valid handle for key 2");
1691        }
1692
1693        if let Some(handle3) = lhm.entry_handle(&3) {
1694            assert_eq!(lhm.get_entry(&handle3), Some((&3, &"c")));
1695        } else {
1696            panic!("Expected valid handle for key 3");
1697        }
1698
1699        // Test invalid handle
1700        let invalid_handle = crate::lhmap::entry::EntryHandle::<u16, &str>::default();
1701        assert_eq!(lhm.get_entry(&invalid_handle), None);
1702    }
1703
1704    #[test]
1705    fn test_get_entry_does_not_affect_order() {
1706        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
1707        lhm.put(1, "a");
1708        lhm.put(2, "b");
1709        lhm.put(3, "c");
1710
1711        // Initial order: [1, 2, 3]
1712        let keys_before: Vec<_> = lhm.keys().copied().collect();
1713        assert_eq!(keys_before, vec![1, 2, 3]);
1714
1715        // Get entry using handle - should NOT affect AccessOrder
1716        if let Some(handle1) = lhm.entry_handle(&1) {
1717            assert_eq!(lhm.get_entry(&handle1), Some((&1, &"a")));
1718        }
1719
1720        // Order should remain the same
1721        let keys_after: Vec<_> = lhm.keys().copied().collect();
1722        assert_eq!(keys_after, vec![1, 2, 3]);
1723        assert_eq!(keys_before, keys_after);
1724
1725        // Compare with regular get() which DOES affect AccessOrder
1726        assert_eq!(lhm.get(&1), Some(&"a"));
1727        let keys_after_get: Vec<_> = lhm.keys().copied().collect();
1728        assert_eq!(keys_after_get, vec![2, 3, 1]); // 1 moved to tail
1729    }
1730
1731    #[test]
1732    fn test_get_entry_invalid_after_removal() {
1733        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
1734        lhm.put(1, "a");
1735        lhm.put(2, "b");
1736
1737        // Get handle for key 1
1738        let handle1 = lhm.entry_handle(&1).expect("Expected valid handle");
1739        
1740        // Verify handle works initially
1741        assert_eq!(lhm.get_entry(&handle1), Some((&1, &"a")));
1742
1743        // Remove the entry
1744        assert_eq!(lhm.remove(&1), Some("a"));
1745
1746        // Now the handle should be invalid
1747        assert_eq!(lhm.get_entry(&handle1), None);
1748    }
1749
1750    #[test]
1751    fn test_get_entry_insertion_order() {
1752        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
1753        lhm.put(1, "a");
1754        lhm.put(2, "b");
1755        lhm.put(3, "c");
1756
1757        // Get all handles
1758        let handle1 = lhm.entry_handle(&1).unwrap();
1759        let handle2 = lhm.entry_handle(&2).unwrap();
1760        let handle3 = lhm.entry_handle(&3).unwrap();
1761
1762        // Access entries in different order - should not affect iteration order
1763        assert_eq!(lhm.get_entry(&handle3), Some((&3, &"c")));
1764        assert_eq!(lhm.get_entry(&handle1), Some((&1, &"a")));
1765        assert_eq!(lhm.get_entry(&handle2), Some((&2, &"b")));
1766
1767        // Iteration order should remain unchanged
1768        let keys: Vec<_> = lhm.keys().copied().collect();
1769        assert_eq!(keys, vec![1, 2, 3]);
1770    }
1771
1772    #[test]
1773    fn test_get_entry_with_handle_operations() {
1774        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
1775        lhm.put(1, "a");
1776        lhm.put(2, "b");
1777        lhm.put(3, "c");
1778
1779        // Get handle and verify initial state
1780        let handle2 = lhm.entry_handle(&2).unwrap();
1781        assert_eq!(lhm.get_entry(&handle2), Some((&2, &"b")));
1782
1783        // Move entry to tail using handle
1784        assert!(lhm.make_tail(handle2.clone()));
1785        
1786        // Handle should still be valid and return same data
1787        assert_eq!(lhm.get_entry(&handle2), Some((&2, &"b")));
1788        
1789        // But iteration order should have changed
1790        let keys: Vec<_> = lhm.keys().copied().collect();
1791        assert_eq!(keys, vec![1, 3, 2]);
1792
1793        // Move entry to head using handle
1794        assert!(lhm.make_head(handle2.clone()));
1795        
1796        // Handle should still be valid
1797        assert_eq!(lhm.get_entry(&handle2), Some((&2, &"b")));
1798        
1799        // Iteration order should have changed again
1800        let keys: Vec<_> = lhm.keys().copied().collect();
1801        assert_eq!(keys, vec![2, 1, 3]);
1802    }
1803
1804    #[test]
1805    fn test_get_key_basic() {
1806        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
1807        lhm.put(1, "a");
1808        lhm.put(2, "b");
1809        lhm.put(3, "c");
1810
1811        // Test getting valid keys
1812        if let Some(handle1) = lhm.entry_handle(&1) {
1813            assert_eq!(lhm.get_key(&handle1), Some(&1));
1814        } else {
1815            panic!("Expected valid handle for key 1");
1816        }
1817
1818        if let Some(handle2) = lhm.entry_handle(&2) {
1819            assert_eq!(lhm.get_key(&handle2), Some(&2));
1820        } else {
1821            panic!("Expected valid handle for key 2");
1822        }
1823
1824        if let Some(handle3) = lhm.entry_handle(&3) {
1825            assert_eq!(lhm.get_key(&handle3), Some(&3));
1826        } else {
1827            panic!("Expected valid handle for key 3");
1828        }
1829
1830        // Test invalid handle
1831        let invalid_handle = crate::lhmap::entry::EntryHandle::<u16, &str>::default();
1832        assert_eq!(lhm.get_key(&invalid_handle), None);
1833    }
1834
1835    #[test]
1836    fn test_get_key_does_not_affect_order() {
1837        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
1838        lhm.put(1, "a");
1839        lhm.put(2, "b");
1840        lhm.put(3, "c");
1841
1842        // Initial order: [1, 2, 3]
1843        let keys_before: Vec<_> = lhm.keys().copied().collect();
1844        assert_eq!(keys_before, vec![1, 2, 3]);
1845
1846        // Get key using handle - should NOT affect AccessOrder
1847        if let Some(handle1) = lhm.entry_handle(&1) {
1848            assert_eq!(lhm.get_key(&handle1), Some(&1));
1849        }
1850
1851        // Order should remain the same
1852        let keys_after: Vec<_> = lhm.keys().copied().collect();
1853        assert_eq!(keys_after, vec![1, 2, 3]);
1854        assert_eq!(keys_before, keys_after);
1855    }
1856
1857    #[test]
1858    fn test_get_key_invalid_after_removal() {
1859        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
1860        lhm.put(1, "a");
1861        lhm.put(2, "b");
1862
1863        // Get handle for key 1
1864        let handle1 = lhm.entry_handle(&1).expect("Expected valid handle");
1865        
1866        // Verify handle works initially
1867        assert_eq!(lhm.get_key(&handle1), Some(&1));
1868
1869        // Remove the entry
1870        assert_eq!(lhm.remove(&1), Some("a"));
1871
1872        // Now the handle should be invalid
1873        assert_eq!(lhm.get_key(&handle1), None);
1874    }
1875
1876    #[test]
1877    fn test_get_value_basic() {
1878        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
1879        lhm.put(1, "a");
1880        lhm.put(2, "b");
1881        lhm.put(3, "c");
1882
1883        // Test getting valid values
1884        if let Some(handle1) = lhm.entry_handle(&1) {
1885            assert_eq!(lhm.get_value(&handle1), Some(&"a"));
1886        } else {
1887            panic!("Expected valid handle for key 1");
1888        }
1889
1890        if let Some(handle2) = lhm.entry_handle(&2) {
1891            assert_eq!(lhm.get_value(&handle2), Some(&"b"));
1892        } else {
1893            panic!("Expected valid handle for key 2");
1894        }
1895
1896        if let Some(handle3) = lhm.entry_handle(&3) {
1897            assert_eq!(lhm.get_value(&handle3), Some(&"c"));
1898        } else {
1899            panic!("Expected valid handle for key 3");
1900        }
1901
1902        // Test invalid handle
1903        let invalid_handle = crate::lhmap::entry::EntryHandle::<u16, &str>::default();
1904        assert_eq!(lhm.get_value(&invalid_handle), None);
1905    }
1906
1907    #[test]
1908    fn test_get_value_does_not_affect_order() {
1909        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
1910        lhm.put(1, "a");
1911        lhm.put(2, "b");
1912        lhm.put(3, "c");
1913
1914        // Initial order: [1, 2, 3]
1915        let keys_before: Vec<_> = lhm.keys().copied().collect();
1916        assert_eq!(keys_before, vec![1, 2, 3]);
1917
1918        // Get value using handle - should NOT affect AccessOrder
1919        if let Some(handle1) = lhm.entry_handle(&1) {
1920            assert_eq!(lhm.get_value(&handle1), Some(&"a"));
1921        }
1922
1923        // Order should remain the same
1924        let keys_after: Vec<_> = lhm.keys().copied().collect();
1925        assert_eq!(keys_after, vec![1, 2, 3]);
1926        assert_eq!(keys_before, keys_after);
1927    }
1928
1929    #[test]
1930    fn test_get_value_invalid_after_removal() {
1931        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
1932        lhm.put(1, "a");
1933        lhm.put(2, "b");
1934
1935        // Get handle for key 1
1936        let handle1 = lhm.entry_handle(&1).expect("Expected valid handle");
1937        
1938        // Verify handle works initially
1939        assert_eq!(lhm.get_value(&handle1), Some(&"a"));
1940
1941        // Remove the entry
1942        assert_eq!(lhm.remove(&1), Some("a"));
1943
1944        // Now the handle should be invalid
1945        assert_eq!(lhm.get_value(&handle1), None);
1946    }
1947
1948    #[test]
1949    fn test_get_value_mut_basic() {
1950        let mut lhm = LinkedHashMap::<u16, String>::new(10, Order::InsertionOrder, None);
1951        lhm.put(1, "a".to_string());
1952        lhm.put(2, "b".to_string());
1953        lhm.put(3, "c".to_string());
1954
1955        // Test getting and modifying valid values
1956        if let Some(handle1) = lhm.entry_handle(&1) {
1957            if let Some(value) = lhm.get_value_mut(&handle1) {
1958                assert_eq!(value, &"a".to_string());
1959                value.push_str("_modified");
1960                assert_eq!(value, &"a_modified".to_string());
1961            } else {
1962                panic!("Expected valid mutable value for key 1");
1963            }
1964        } else {
1965            panic!("Expected valid handle for key 1");
1966        }
1967
1968        // Verify the change persisted
1969        if let Some(handle1) = lhm.entry_handle(&1) {
1970            assert_eq!(lhm.get_value(&handle1), Some(&"a_modified".to_string()));
1971        }
1972
1973        // Test invalid handle
1974        let invalid_handle = crate::lhmap::entry::EntryHandle::<u16, String>::default();
1975        assert_eq!(lhm.get_value_mut(&invalid_handle), None);
1976    }
1977
1978    #[test]
1979    fn test_get_value_mut_does_not_affect_order() {
1980        let mut lhm = LinkedHashMap::<u16, String>::new(10, Order::AccessOrder, None);
1981        lhm.put(1, "a".to_string());
1982        lhm.put(2, "b".to_string());
1983        lhm.put(3, "c".to_string());
1984
1985        // Initial order: [1, 2, 3]
1986        let keys_before: Vec<_> = lhm.keys().copied().collect();
1987        assert_eq!(keys_before, vec![1, 2, 3]);
1988
1989        // Modify value using handle - should NOT affect AccessOrder
1990        if let Some(handle1) = lhm.entry_handle(&1) {
1991            if let Some(value) = lhm.get_value_mut(&handle1) {
1992                value.push_str("_modified");
1993            }
1994        }
1995
1996        // Order should remain the same even after mutation
1997        let keys_after: Vec<_> = lhm.keys().copied().collect();
1998        assert_eq!(keys_after, vec![1, 2, 3]);
1999        assert_eq!(keys_before, keys_after);
2000
2001        // Verify the modification worked
2002        if let Some(handle1) = lhm.entry_handle(&1) {
2003            assert_eq!(lhm.get_value(&handle1), Some(&"a_modified".to_string()));
2004        }
2005    }
2006
2007    #[test]
2008    fn test_get_value_mut_invalid_after_removal() {
2009        let mut lhm = LinkedHashMap::<u16, String>::new(10, Order::InsertionOrder, None);
2010        lhm.put(1, "a".to_string());
2011        lhm.put(2, "b".to_string());
2012
2013        // Get handle for key 1
2014        let handle1 = lhm.entry_handle(&1).expect("Expected valid handle");
2015        
2016        // Verify handle works initially
2017        if let Some(value) = lhm.get_value_mut(&handle1) {
2018            value.push_str("_test");
2019        }
2020        assert_eq!(lhm.get_value(&lhm.entry_handle(&1).unwrap()), Some(&"a_test".to_string()));
2021
2022        // Remove the entry
2023        assert_eq!(lhm.remove(&1), Some("a_test".to_string()));
2024
2025        // Now the handle should be invalid
2026        assert_eq!(lhm.get_value_mut(&handle1), None);
2027    }
2028
2029    #[test]
2030    fn test_get_key_value_mut_integration() {
2031        let mut lhm = LinkedHashMap::<u16, String>::new(10, Order::InsertionOrder, None);
2032        lhm.put(1, "a".to_string());
2033        lhm.put(2, "b".to_string());
2034        lhm.put(3, "c".to_string());
2035
2036        // Get handle and test all access methods
2037        if let Some(handle2) = lhm.entry_handle(&2) {
2038            // Test key access
2039            assert_eq!(lhm.get_key(&handle2), Some(&2));
2040            
2041            // Test value access
2042            assert_eq!(lhm.get_value(&handle2), Some(&"b".to_string()));
2043            
2044            // Test mutable value access and modification
2045            if let Some(value) = lhm.get_value_mut(&handle2) {
2046                value.push_str("_updated");
2047            }
2048            
2049            // Verify modification through immutable access
2050            assert_eq!(lhm.get_value(&handle2), Some(&"b_updated".to_string()));
2051            
2052            // Test handle operations still work after mutations
2053            assert!(lhm.make_tail(handle2.clone()));
2054            
2055            // Verify all access methods still work after repositioning
2056            assert_eq!(lhm.get_key(&handle2), Some(&2));
2057            assert_eq!(lhm.get_value(&handle2), Some(&"b_updated".to_string()));
2058        } else {
2059            panic!("Expected valid handle for key 2");
2060        }
2061
2062        // Verify final state
2063        let keys: Vec<_> = lhm.keys().copied().collect();
2064        assert_eq!(keys, vec![1, 3, 2]); // 2 moved to tail
2065        
2066        let values: Vec<_> = lhm.values().cloned().collect();
2067        assert_eq!(values, vec!["a".to_string(), "c".to_string(), "b_updated".to_string()]);
2068    }
2069
2070    #[test]
2071    fn test_make_head_basic() {
2072        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
2073        lhm.put(1, "a");
2074        lhm.put(2, "b");
2075        lhm.put(3, "c");
2076
2077        // Initial order: [1, 2, 3]
2078        let keys: Vec<_> = lhm.keys().copied().collect();
2079        assert_eq!(keys, vec![1, 2, 3]);
2080
2081        // Move key 3 to head
2082        if let Some(handle) = lhm.entry_handle(&3) {
2083            assert!(lhm.make_head(handle));
2084        }
2085
2086        // Order should now be [3, 1, 2]
2087        let keys: Vec<_> = lhm.keys().copied().collect();
2088        assert_eq!(keys, vec![3, 1, 2]);
2089
2090        // Values should remain unchanged
2091        assert_eq!(lhm.get(&1), Some(&"a"));
2092        assert_eq!(lhm.get(&2), Some(&"b"));
2093        assert_eq!(lhm.get(&3), Some(&"c"));
2094    }
2095
2096    #[test]
2097    fn test_make_head_already_at_head() {
2098        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
2099        lhm.put(1, "a");
2100        lhm.put(2, "b");
2101        lhm.put(3, "c");
2102
2103        // Move key 1 to head (it's already at head)
2104        if let Some(handle) = lhm.entry_handle(&1) {
2105            assert!(lhm.make_head(handle));
2106        }
2107
2108        // Order should remain the same: [1, 2, 3]
2109        let keys: Vec<_> = lhm.keys().copied().collect();
2110        assert_eq!(keys, vec![1, 2, 3]);
2111    }
2112
2113    #[test]
2114    fn test_make_head_access_order() {
2115        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
2116        lhm.put(1, "a");
2117        lhm.put(2, "b");
2118        lhm.put(3, "c");
2119
2120        // Initial order: [1, 2, 3]
2121        let keys: Vec<_> = lhm.keys().copied().collect();
2122        assert_eq!(keys, vec![1, 2, 3]);
2123
2124        // Move key 2 to head using handle
2125        if let Some(handle) = lhm.entry_handle(&2) {
2126            assert!(lhm.make_head(handle));
2127        }
2128
2129        // Order should now be [2, 1, 3]
2130        let keys: Vec<_> = lhm.keys().copied().collect();
2131        assert_eq!(keys, vec![2, 1, 3]);
2132    }
2133
2134    #[test]
2135    fn test_make_head_invalid_handle() {
2136        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
2137        lhm.put(1, "a");
2138
2139        // Create a default handle (invalid)
2140        let default_handle = crate::lhmap::entry::EntryHandle::<u16, &str>::default();
2141        
2142        // Try to use it - should return false
2143        assert_eq!(lhm.make_head(default_handle), false);
2144    }
2145
2146    #[test]
2147    fn test_remove_head_basic() {
2148        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
2149        lhm.put(1, "a");
2150        lhm.put(2, "b");
2151        lhm.put(3, "c");
2152
2153        // Remove head entries in order
2154        assert_eq!(lhm.remove_head(), Some((1, "a")));
2155        assert_eq!(lhm.len(), 2);
2156        
2157        assert_eq!(lhm.remove_head(), Some((2, "b")));
2158        assert_eq!(lhm.len(), 1);
2159        
2160        assert_eq!(lhm.remove_head(), Some((3, "c")));
2161        assert_eq!(lhm.len(), 0);
2162        
2163        // Empty map returns None
2164        assert_eq!(lhm.remove_head(), None);
2165    }
2166
2167    #[test]
2168    fn test_remove_head_access_order() {
2169        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
2170        lhm.put(1, "a");
2171        lhm.put(2, "b");
2172        lhm.put(3, "c");
2173
2174        // Access key 2, making it most recently used (moves to tail)
2175        lhm.get(&2);
2176
2177        // Order should now be [1, 3, 2]
2178        let keys: Vec<_> = lhm.keys().copied().collect();
2179        assert_eq!(keys, vec![1, 3, 2]);
2180
2181        // Remove head should remove 1 (least recently used)
2182        assert_eq!(lhm.remove_head(), Some((1, "a")));
2183        
2184        let keys: Vec<_> = lhm.keys().copied().collect();
2185        assert_eq!(keys, vec![3, 2]);
2186    }
2187
2188    #[test]
2189    fn test_remove_tail_basic() {
2190        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
2191        lhm.put(1, "a");
2192        lhm.put(2, "b");
2193        lhm.put(3, "c");
2194
2195        // Remove tail entries in reverse order
2196        assert_eq!(lhm.remove_tail(), Some((3, "c")));
2197        assert_eq!(lhm.len(), 2);
2198        
2199        assert_eq!(lhm.remove_tail(), Some((2, "b")));
2200        assert_eq!(lhm.len(), 1);
2201        
2202        assert_eq!(lhm.remove_tail(), Some((1, "a")));
2203        assert_eq!(lhm.len(), 0);
2204        
2205        // Empty map returns None
2206        assert_eq!(lhm.remove_tail(), None);
2207    }
2208
2209    #[test]
2210    fn test_remove_tail_access_order() {
2211        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
2212        lhm.put(1, "a");
2213        lhm.put(2, "b");
2214        lhm.put(3, "c");
2215
2216        // Access key 1, making it most recently used (moves to tail)
2217        lhm.get(&1);
2218
2219        // Order should now be [2, 3, 1]
2220        let keys: Vec<_> = lhm.keys().copied().collect();
2221        assert_eq!(keys, vec![2, 3, 1]);
2222
2223        // Remove tail should remove 1 (most recently used)
2224        assert_eq!(lhm.remove_tail(), Some((1, "a")));
2225        
2226        let keys: Vec<_> = lhm.keys().copied().collect();
2227        assert_eq!(keys, vec![2, 3]);
2228    }
2229
2230    #[test]
2231    fn test_remove_empty_map() {
2232        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
2233        
2234        // Both methods should return None for empty map
2235        assert_eq!(lhm.remove_head(), None);
2236        assert_eq!(lhm.remove_tail(), None);
2237    }
2238
2239    #[test]
2240    fn test_remove_single_element() {
2241        // Test remove_head with single element
2242        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
2243        lhm.put(1, "a");
2244        assert_eq!(lhm.remove_head(), Some((1, "a")));
2245        assert!(lhm.is_empty());
2246
2247        // Test remove_tail with single element
2248        let mut lhm2 = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
2249        lhm2.put(1, "a");
2250        assert_eq!(lhm2.remove_tail(), Some((1, "a")));
2251        assert!(lhm2.is_empty());
2252    }
2253
2254    #[test]
2255    fn test_make_head_and_tail_integration() {
2256        let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
2257        lhm.put(1, "a");
2258        lhm.put(2, "b");
2259        lhm.put(3, "c");
2260        lhm.put(4, "d");
2261
2262        // Initial order: [1, 2, 3, 4]
2263        let keys: Vec<_> = lhm.keys().copied().collect();
2264        assert_eq!(keys, vec![1, 2, 3, 4]);
2265
2266        // Move 3 to head: [3, 1, 2, 4]
2267        if let Some(handle) = lhm.entry_handle(&3) {
2268            assert!(lhm.make_head(handle));
2269        }
2270        let keys: Vec<_> = lhm.keys().copied().collect();
2271        assert_eq!(keys, vec![3, 1, 2, 4]);
2272
2273        // Move 1 to tail: [3, 2, 4, 1]
2274        if let Some(handle) = lhm.entry_handle(&1) {
2275            assert!(lhm.make_tail(handle));
2276        }
2277        let keys: Vec<_> = lhm.keys().copied().collect();
2278        assert_eq!(keys, vec![3, 2, 4, 1]);
2279
2280        // Remove head and tail
2281        assert_eq!(lhm.remove_head(), Some((3, "c")));
2282        assert_eq!(lhm.remove_tail(), Some((1, "a")));
2283
2284        // Should have [2, 4] left
2285        let keys: Vec<_> = lhm.keys().copied().collect();
2286        assert_eq!(keys, vec![2, 4]);
2287    }
2288
2289    #[test]
2290    fn test_head() {
2291        let mut lhm: LinkedHashMap<u16, &str> = LinkedHashMap::new(10, Order::InsertionOrder, None);
2292
2293        // Empty map should return None
2294        assert_eq!(lhm.head(), None);
2295
2296        // Add some entries
2297        lhm.put(1, "a");
2298        assert_eq!(lhm.head(), Some((&1, &"a")));
2299
2300        lhm.put(2, "b");
2301        assert_eq!(lhm.head(), Some((&1, &"a"))); // Head should still be first inserted
2302
2303        lhm.put(3, "c");
2304        assert_eq!(lhm.head(), Some((&1, &"a"))); // Head should still be first inserted
2305
2306        // Remove head and check next becomes head
2307        assert_eq!(lhm.remove_head(), Some((1, "a")));
2308        assert_eq!(lhm.head(), Some((&2, &"b")));
2309
2310        assert_eq!(lhm.remove_head(), Some((2, "b")));
2311        assert_eq!(lhm.head(), Some((&3, &"c")));
2312
2313        assert_eq!(lhm.remove_head(), Some((3, "c")));
2314        assert_eq!(lhm.head(), None);
2315    }
2316
2317    #[test]
2318    fn test_head_access_order() {
2319        let mut lhm: LinkedHashMap<u16, &str> = LinkedHashMap::new(10, Order::AccessOrder, None);
2320
2321        // Add entries
2322        lhm.put(1, "a");
2323        lhm.put(2, "b");
2324        lhm.put(3, "c");
2325
2326        // Head should be least recently accessed (first inserted)
2327        assert_eq!(lhm.head(), Some((&1, &"a")));
2328
2329        // Access element 1 - it should move to tail, making 2 the new head
2330        lhm.get(&1);
2331        assert_eq!(lhm.head(), Some((&2, &"b")));
2332
2333        // Access element 2 - it should move to tail, making 3 the new head
2334        lhm.get(&2);
2335        assert_eq!(lhm.head(), Some((&3, &"c")));
2336    }
2337
2338    #[test]
2339    fn test_tail() {
2340        let mut lhm: LinkedHashMap<u16, &str> = LinkedHashMap::new(10, Order::InsertionOrder, None);
2341
2342        // Empty map should return None
2343        assert_eq!(lhm.tail(), None);
2344
2345        // Add some entries
2346        lhm.put(1, "a");
2347        assert_eq!(lhm.tail(), Some((&1, &"a")));
2348
2349        lhm.put(2, "b");
2350        assert_eq!(lhm.tail(), Some((&2, &"b"))); // Tail should be last inserted
2351
2352        lhm.put(3, "c");
2353        assert_eq!(lhm.tail(), Some((&3, &"c"))); // Tail should be last inserted
2354
2355        // Remove tail and check previous becomes tail
2356        assert_eq!(lhm.remove_tail(), Some((3, "c")));
2357        assert_eq!(lhm.tail(), Some((&2, &"b")));
2358
2359        assert_eq!(lhm.remove_tail(), Some((2, "b")));
2360        assert_eq!(lhm.tail(), Some((&1, &"a")));
2361
2362        assert_eq!(lhm.remove_tail(), Some((1, "a")));
2363        assert_eq!(lhm.tail(), None);
2364    }
2365
2366    #[test]
2367    fn test_tail_access_order() {
2368        let mut lhm: LinkedHashMap<u16, &str> = LinkedHashMap::new(10, Order::AccessOrder, None);
2369
2370        // Add entries
2371        lhm.put(1, "a");
2372        lhm.put(2, "b");
2373        lhm.put(3, "c");
2374
2375        // Tail should be most recently accessed (last inserted)
2376        assert_eq!(lhm.tail(), Some((&3, &"c")));
2377
2378        // Access element 1 - it should move to tail
2379        lhm.get(&1);
2380        assert_eq!(lhm.tail(), Some((&1, &"a")));
2381
2382        // Access element 2 - it should move to tail
2383        lhm.get(&2);
2384        assert_eq!(lhm.tail(), Some((&2, &"b")));
2385    }
2386}