Skip to content

Commit 90f72af

Browse files
Your NameJupeyy
authored andcommitted
Add iter_at_key & iter_at_key_mut
An iterator that was skipped to a specific key entry, which allows to iterate starting from this entry, instead of starting at the beginning
1 parent 9cd8c09 commit 90f72af

File tree

2 files changed

+379
-0
lines changed

2 files changed

+379
-0
lines changed

src/linked_hash_map.rs

Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,114 @@ where
531531
}
532532
}
533533
}
534+
535+
/// Returns iterator that was skipped to a specific key entry, or None.
536+
/// It does not implement `ExactSizeIterator` because
537+
/// it is unclear where exactly the iterator is.
538+
///
539+
/// It is useful when iterating over a subset of
540+
/// all items in order, e.g. for a starting queue at a specific key
541+
///
542+
/// # Examples
543+
///
544+
/// ```rs
545+
///
546+
/// let mut map = LinkedHashMap::new();
547+
///
548+
/// map.insert("a", 10);
549+
/// map.insert("b", 20);
550+
/// map.insert("c", 30);
551+
///
552+
/// assert_eq!(map.iter_at_key(&"e").is_none(), true);
553+
///
554+
/// let mut iter = map.iter_at_key(&"b").unwrap();
555+
/// assert_eq!((&"b", &20), iter.next().unwrap());
556+
/// assert_eq!((&"c", &30), iter.next().unwrap());
557+
/// assert_eq!(None, iter.next());
558+
/// assert_eq!(None, iter.next());
559+
/// ```
560+
///
561+
#[inline]
562+
pub fn iter_at_key(&self, k: &K) -> Option<IterAtKey<'_, K, V>> {
563+
let head_tail = if let Some(values) = self.values {
564+
let ValueLinks { next, prev } = unsafe { values.as_ref().links.value };
565+
Some((next, prev))
566+
} else {
567+
None
568+
};
569+
570+
match head_tail {
571+
Some((head, tail)) => match self.raw_entry().node_from_key(k) {
572+
Some(entry) => Some(IterAtKey {
573+
iter: Iter {
574+
head: head.as_ptr(),
575+
tail: tail.as_ptr(),
576+
remaining: usize::MAX,
577+
marker: PhantomData,
578+
},
579+
cur: entry.as_ptr(),
580+
}),
581+
None => None,
582+
},
583+
None => None,
584+
}
585+
}
586+
587+
/// Returns a mutable iterator that was skipped to a specific key entry, or None.
588+
/// It does not implement `ExactSizeIterator` because
589+
/// it is unclear where exactly the iterator is.
590+
///
591+
/// It is useful when iterating over a subset of
592+
/// all items in order, e.g. for a queue starting at a specific key
593+
///
594+
/// # Examples
595+
///
596+
/// ```rs
597+
/// let mut map = LinkedHashMap::new();
598+
/// map.insert("a", 10);
599+
/// map.insert("c", 30);
600+
/// map.insert("b", 20);
601+
/// map.insert("d", 40);
602+
///
603+
/// assert_eq!(map.iter_at_key_mut(&"e").is_none(), true);
604+
///
605+
/// let mut iter = map.iter_at_key_mut(&"c").unwrap();
606+
/// let entry = iter.next().unwrap();
607+
/// assert_eq!("c", *entry.0);
608+
/// *entry.1 = 17;
609+
///
610+
/// assert_eq!(format!("{:?}", iter), "[(\"b\", 20), (\"d\", 40)]");
611+
/// assert_eq!(17, map[&"c"]);
612+
/// ```
613+
///
614+
#[inline]
615+
pub fn iter_at_key_mut(&mut self, k: &K) -> Option<IterMutAtKey<'_, K, V>> {
616+
let head_tail = if let Some(values) = self.values {
617+
let ValueLinks { next, prev } = unsafe { values.as_ref().links.value };
618+
Some((next, prev))
619+
} else {
620+
None
621+
};
622+
623+
match head_tail {
624+
Some((head, tail)) => match self.raw_entry_mut().from_key(k) {
625+
RawEntryMut::Occupied(entry) => {
626+
let cur = entry.entry.key();
627+
Some(IterMutAtKey {
628+
iter: IterMut {
629+
head: Some(head),
630+
tail: Some(tail),
631+
remaining: usize::MAX,
632+
marker: PhantomData,
633+
},
634+
cur: Some(*cur),
635+
})
636+
}
637+
RawEntryMut::Vacant(_) => None,
638+
},
639+
None => None,
640+
}
641+
}
534642
}
535643

536644
impl<K, V, S> LinkedHashMap<K, V, S>
@@ -938,6 +1046,16 @@ where
9381046
self.from_key_hashed_nocheck(hash, k)
9391047
}
9401048

1049+
#[inline]
1050+
fn node_from_key<Q>(self, k: &Q) -> Option<NonNull<Node<K, V>>>
1051+
where
1052+
K: Borrow<Q>,
1053+
Q: Hash + Eq + ?Sized,
1054+
{
1055+
let hash = hash_key(self.hash_builder, k);
1056+
self.node_from_key_hashed_nocheck(hash, k)
1057+
}
1058+
9411059
#[inline]
9421060
pub fn from_key_hashed_nocheck<Q>(self, hash: u64, k: &Q) -> Option<(&'a K, &'a V)>
9431061
where
@@ -947,6 +1065,15 @@ where
9471065
self.from_hash(hash, move |o| k.eq(o.borrow()))
9481066
}
9491067

1068+
#[inline]
1069+
fn node_from_key_hashed_nocheck<Q>(self, hash: u64, k: &Q) -> Option<NonNull<Node<K, V>>>
1070+
where
1071+
K: Borrow<Q>,
1072+
Q: Hash + Eq + ?Sized,
1073+
{
1074+
self.node_from_hash(hash, move |o| k.eq(o.borrow()))
1075+
}
1076+
9501077
#[inline]
9511078
pub fn from_hash(
9521079
self,
@@ -963,6 +1090,22 @@ where
9631090
Some((key, value))
9641091
}
9651092
}
1093+
1094+
#[inline]
1095+
fn node_from_hash(
1096+
self,
1097+
hash: u64,
1098+
mut is_match: impl FnMut(&K) -> bool,
1099+
) -> Option<NonNull<Node<K, V>>> {
1100+
unsafe {
1101+
let node = *self
1102+
.entry
1103+
.from_hash(hash, move |k| is_match((*k).as_ref().key_ref()))?
1104+
.0;
1105+
1106+
Some(node)
1107+
}
1108+
}
9661109
}
9671110

9681111
unsafe impl<'a, K, V, S> Send for RawEntryBuilder<'a, K, V, S>
@@ -1384,6 +1527,16 @@ pub struct Drain<'a, K, V> {
13841527
marker: PhantomData<(K, V, &'a LinkedHashMap<K, V>)>,
13851528
}
13861529

1530+
pub struct IterAtKey<'a, K, V> {
1531+
iter: Iter<'a, K, V>,
1532+
cur: *const Node<K, V>,
1533+
}
1534+
1535+
pub struct IterMutAtKey<'a, K, V> {
1536+
iter: IterMut<'a, K, V>,
1537+
cur: Option<NonNull<Node<K, V>>>,
1538+
}
1539+
13871540
impl<K, V> IterMut<'_, K, V> {
13881541
#[inline]
13891542
pub(crate) fn iter(&self) -> Iter<'_, K, V> {
@@ -1420,6 +1573,21 @@ impl<K, V> Drain<'_, K, V> {
14201573
}
14211574
}
14221575

1576+
impl<K, V> IterMutAtKey<'_, K, V> {
1577+
#[inline]
1578+
pub(crate) fn iter(&self) -> IterAtKey<'_, K, V> {
1579+
IterAtKey {
1580+
iter: Iter {
1581+
head: self.iter.head.as_ptr(),
1582+
tail: self.iter.tail.as_ptr(),
1583+
remaining: self.iter.remaining,
1584+
marker: PhantomData,
1585+
},
1586+
cur: self.cur.as_ptr(),
1587+
}
1588+
}
1589+
}
1590+
14231591
unsafe impl<'a, K, V> Send for Iter<'a, K, V>
14241592
where
14251593
K: Send,
@@ -1448,6 +1616,20 @@ where
14481616
{
14491617
}
14501618

1619+
unsafe impl<'a, K, V> Send for IterAtKey<'a, K, V>
1620+
where
1621+
K: Send,
1622+
V: Send,
1623+
{
1624+
}
1625+
1626+
unsafe impl<'a, K, V> Send for IterMutAtKey<'a, K, V>
1627+
where
1628+
K: Send,
1629+
V: Send,
1630+
{
1631+
}
1632+
14511633
unsafe impl<'a, K, V> Sync for Iter<'a, K, V>
14521634
where
14531635
K: Sync,
@@ -1476,13 +1658,37 @@ where
14761658
{
14771659
}
14781660

1661+
unsafe impl<'a, K, V> Sync for IterAtKey<'a, K, V>
1662+
where
1663+
K: Sync,
1664+
V: Sync,
1665+
{
1666+
}
1667+
1668+
unsafe impl<'a, K, V> Sync for IterMutAtKey<'a, K, V>
1669+
where
1670+
K: Sync,
1671+
V: Sync,
1672+
{
1673+
}
1674+
14791675
impl<'a, K, V> Clone for Iter<'a, K, V> {
14801676
#[inline]
14811677
fn clone(&self) -> Self {
14821678
Iter { ..*self }
14831679
}
14841680
}
14851681

1682+
impl<'a, K, V> Clone for IterAtKey<'a, K, V> {
1683+
#[inline]
1684+
fn clone(&self) -> Self {
1685+
IterAtKey {
1686+
iter: self.iter.clone(),
1687+
cur: self.cur,
1688+
}
1689+
}
1690+
}
1691+
14861692
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for Iter<'_, K, V> {
14871693
#[inline]
14881694
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -1523,6 +1729,28 @@ where
15231729
}
15241730
}
15251731

1732+
impl<K, V> fmt::Debug for IterAtKey<'_, K, V>
1733+
where
1734+
K: fmt::Debug,
1735+
V: fmt::Debug,
1736+
{
1737+
#[inline]
1738+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1739+
f.debug_list().entries(self.clone()).finish()
1740+
}
1741+
}
1742+
1743+
impl<K, V> fmt::Debug for IterMutAtKey<'_, K, V>
1744+
where
1745+
K: fmt::Debug,
1746+
V: fmt::Debug,
1747+
{
1748+
#[inline]
1749+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1750+
f.debug_list().entries(self.iter()).finish()
1751+
}
1752+
}
1753+
15261754
impl<'a, K, V> Iterator for Iter<'a, K, V> {
15271755
type Item = (&'a K, &'a V);
15281756

@@ -1617,6 +1845,47 @@ impl<'a, K, V> Iterator for Drain<'a, K, V> {
16171845
}
16181846
}
16191847

1848+
impl<'a, K, V> Iterator for IterAtKey<'a, K, V> {
1849+
type Item = (&'a K, &'a V);
1850+
1851+
#[inline]
1852+
fn next(&mut self) -> Option<(&'a K, &'a V)> {
1853+
if self.cur.is_null() {
1854+
return None;
1855+
}
1856+
unsafe {
1857+
let last_iter = self.cur == self.iter.tail;
1858+
let (key, value) = (*self.cur).entry_ref();
1859+
self.cur = (*self.cur).links.value.next.as_ptr();
1860+
if last_iter {
1861+
self.cur = std::ptr::null();
1862+
}
1863+
Some((key, value))
1864+
}
1865+
}
1866+
}
1867+
1868+
impl<'a, K, V> Iterator for IterMutAtKey<'a, K, V> {
1869+
type Item = (&'a K, &'a mut V);
1870+
1871+
#[inline]
1872+
fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
1873+
if self.cur.is_none() {
1874+
None
1875+
} else {
1876+
unsafe {
1877+
let last_iter = self.cur == self.iter.tail;
1878+
let (key, value) = (*self.cur.as_ptr()).entry_mut();
1879+
self.cur = Some((*self.cur.as_ptr()).links.value.next);
1880+
if last_iter {
1881+
self.cur = None;
1882+
}
1883+
Some((key, value))
1884+
}
1885+
}
1886+
}
1887+
}
1888+
16201889
impl<'a, K, V> DoubleEndedIterator for Iter<'a, K, V> {
16211890
#[inline]
16221891
fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
@@ -1683,6 +1952,42 @@ impl<'a, K, V> DoubleEndedIterator for Drain<'a, K, V> {
16831952
}
16841953
}
16851954

1955+
impl<'a, K, V> DoubleEndedIterator for IterAtKey<'a, K, V> {
1956+
#[inline]
1957+
fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
1958+
if self.cur.is_null() {
1959+
None
1960+
} else {
1961+
unsafe {
1962+
if self.cur == self.iter.tail {
1963+
self.cur = std::ptr::null();
1964+
}
1965+
let (key, value) = (*self.iter.tail).entry_ref();
1966+
self.iter.tail = (*self.iter.tail).links.value.prev.as_ptr();
1967+
Some((key, value))
1968+
}
1969+
}
1970+
}
1971+
}
1972+
1973+
impl<'a, K, V> DoubleEndedIterator for IterMutAtKey<'a, K, V> {
1974+
#[inline]
1975+
fn next_back(&mut self) -> Option<(&'a K, &'a mut V)> {
1976+
if self.cur.is_none() {
1977+
None
1978+
} else {
1979+
unsafe {
1980+
if self.cur == self.iter.tail {
1981+
self.cur = None;
1982+
}
1983+
let (key, value) = (*self.iter.tail.as_ptr()).entry_mut();
1984+
self.iter.tail = Some((*self.iter.tail.as_ptr()).links.value.prev);
1985+
Some((key, value))
1986+
}
1987+
}
1988+
}
1989+
}
1990+
16861991
impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {}
16871992

16881993
impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {}

0 commit comments

Comments
 (0)