fn diff_keyed_middle(&mut self, old: &'bump [VNode<'bump>], new: &'bump [VNode<'bump>]) {
        /*
        1. Map the old keys into a numerical ordering based on indices.
        2. Create a map of old key to its index
        3. Map each new key to the old key, carrying over the old index.
            - IE if we have ABCD becomes BACD, our sequence would be 1,0,2,3
            - if we have ABCD to ABDE, our sequence would be 0,1,3,MAX because E doesn't exist

        now, we should have a list of integers that indicates where in the old list the new items map to.

        4. Compute the LIS of this list
            - this indicates the longest list of new children that won't need to be moved.

        5. Identify which nodes need to be removed
        6. Identify which nodes will need to be diffed

        7. Going along each item in the new list, create it and insert it before the next closest item in the LIS.
            - if the item already existed, just move it to the right place.

        8. Finally, generate instructions to remove any old children.
        9. Generate instructions to finally diff children that are the same between both
        */

        // 0. Debug sanity checks
        // Should have already diffed the shared-key prefixes and suffixes.
        debug_assert_ne!(new.first().map(|n| n.key()), old.first().map(|o| o.key()));
        debug_assert_ne!(new.last().map(|n| n.key()), old.last().map(|o| o.key()));

        // 1. Map the old keys into a numerical ordering based on indices.
        // 2. Create a map of old key to its index
        // IE if the keys were A B C, then we would have (A, 1) (B, 2) (C, 3).
        let old_key_to_old_index = old
            .iter()
            .enumerate()
            .map(|(i, o)| (o.key().unwrap(), i))
            .collect::<FxHashMap<_, _>>();

        let mut shared_keys = FxHashSet::default();

        // 3. Map each new key to the old key, carrying over the old index.
        let new_index_to_old_index = new
            .iter()
            .map(|node| {
                let key = node.key().unwrap();
                if let Some(&index) = old_key_to_old_index.get(&key) {
                    shared_keys.insert(key);
                    index
                } else {
                    u32::MAX as usize
                }
            })
            .collect::<Vec<_>>();

        // If none of the old keys are reused by the new children, then we remove all the remaining old children and
        // create the new children afresh.
        if shared_keys.is_empty() {
            if let Some(first_old) = old.get(0) {
                self.remove_nodes(&old[1..], true);
                self.stack
                    .create_children(new, MountType::Replace { old: first_old })
            } else {
                self.stack.create_children(new, MountType::Append {});
            }
            return;
        }

        // 4. Compute the LIS of this list
        let mut lis_sequence = Vec::default();
        lis_sequence.reserve(new_index_to_old_index.len());

        let mut predecessors = vec![0; new_index_to_old_index.len()];
        let mut starts = vec![0; new_index_to_old_index.len()];

        longest_increasing_subsequence::lis_with(
            &new_index_to_old_index,
            &mut lis_sequence,
            |a, b| a < b,
            &mut predecessors,
            &mut starts,
        );

        // the lis comes out backwards, I think. can't quite tell.
        lis_sequence.sort_unstable();

        // if a new node gets u32 max and is at the end, then it might be part of our LIS (because u32 max is a valid LIS)
        if lis_sequence.last().map(|f| new_index_to_old_index[*f]) == Some(u32::MAX as usize) {
            lis_sequence.pop();
        }

        let apply = |new_idx, new_node: &'bump VNode<'bump>, stack: &mut DiffStack<'bump>| {
            let old_index = new_index_to_old_index[new_idx];
            if old_index == u32::MAX as usize {
                stack.create_node(new_node, MountType::Absorb);
            } else {
                // this function should never take LIS indices
                stack.push(DiffInstruction::PrepareMove { node: new_node });
                stack.push(DiffInstruction::Diff {
                    new: new_node,
                    old: &old[old_index],
                });
            }
        };

        // add mount instruction for the last items not covered by the lis
        let first_lis = *lis_sequence.first().unwrap();
        if first_lis > 0 {
            self.stack.push_nodes_created(0);
            self.stack.push(DiffInstruction::Mount {
                and: MountType::InsertBefore {
                    other_node: &new[first_lis],
                },
            });

            for (idx, new_node) in new[..first_lis].iter().enumerate().rev() {
                apply(idx, new_node, &mut self.stack);
            }
        }

        // for each spacing, generate a mount instruction
        let mut lis_iter = lis_sequence.iter().rev();
        let mut last = *lis_iter.next().unwrap();
        for next in lis_iter {
            if last - next > 1 {
                self.stack.push_nodes_created(0);
                self.stack.push(DiffInstruction::Mount {
                    and: MountType::InsertBefore {
                        other_node: &new[last],
                    },
                });
                for (idx, new_node) in new[(next + 1)..last].iter().enumerate().rev() {
                    apply(idx + next + 1, new_node, &mut self.stack);
                }
            }
            last = *next;
        }

        // add mount instruction for the first items not covered by the lis
        let last = *lis_sequence.last().unwrap();
        if last < (new.len() - 1) {
            self.stack.push_nodes_created(0);
            self.stack.push(DiffInstruction::Mount {
                and: MountType::InsertAfter {
                    other_node: &new[last],
                },
            });
            for (idx, new_node) in new[(last + 1)..].iter().enumerate().rev() {
                apply(idx + last + 1, new_node, &mut self.stack);
            }
        }

        for idx in lis_sequence.iter().rev() {
            self.stack.push(DiffInstruction::Diff {
                new: &new[*idx],
                old: &old[new_index_to_old_index[*idx]],
            });
        }
    }
// The most-general, expensive code path for keyed children diffing.
//
// We find the longest subsequence within `old` of children that are relatively
// ordered the same way in `new` (via finding a longest-increasing-subsequence
// of the old child's index within `new`). The children that are elements of
// this subsequence will remain in place, minimizing the number of DOM moves we
// will have to do.
//
// Upon entry to this function, the change list stack must be empty.
//
// This function will load the appropriate nodes onto the stack and do diffing in place.
//
// Upon exit from this function, it will be restored to that same self.
The most-general, expensive code path for keyed children diffing.

Upon entry to this function, the change list stack must be empty.

This function will load the appropriate nodes onto the stack and do diffing in place.

Upon exit from this function, it will be restored to that same self.
The most - general expensive code path for keyed children diffing . Upon entry to this function the change list stack must be empty . This function will load the appropriate nodes onto the stack and do diffing in place . Upon exit from this function it will be restored to that same self .
fn diff_keyed_middle(&mut self, old: &'bump [VNode<'bump>], new: &'bump [VNode<'bump>]) {
        /*
        1. Map the old keys into a numerical ordering based on indices.
        2. Create a map of old key to its index
        3. Map each new key to the old key, carrying over the old index.
            - IE if we have ABCD becomes BACD, our sequence would be 1,0,2,3
            - if we have ABCD to ABDE, our sequence would be 0,1,3,MAX because E doesn't exist
        now, we should have a list of integers that indicates where in the old list the new items map to.
        4. Compute the LIS of this list
            - this indicates the longest list of new children that won't need to be moved.
        5. Identify which nodes need to be removed
        6. Identify which nodes will need to be diffed
        7. Going along each item in the new list, create it and insert it before the next closest item in the LIS.
            - if the item already existed, just move it to the right place.
        8. Finally, generate instructions to remove any old children.
        9. Generate instructions to finally diff children that are the same between both
        */
        // 0. Debug sanity checks
        // Should have already diffed the shared-key prefixes and suffixes.
        debug_assert_ne!(new.first().map(|n| n.key()), old.first().map(|o| o.key()));
        debug_assert_ne!(new.last().map(|n| n.key()), old.last().map(|o| o.key()));
        // 1. Map the old keys into a numerical ordering based on indices.
        // 2. Create a map of old key to its index
        // IE if the keys were A B C, then we would have (A, 1) (B, 2) (C, 3).
        let old_key_to_old_index = old
            .iter()
            .enumerate()
            .map(|(i, o)| (o.key().unwrap(), i))
            .collect::<FxHashMap<_, _>>();
        let mut shared_keys = FxHashSet::default();
        // 3. Map each new key to the old key, carrying over the old index.
        let new_index_to_old_index = new
            .iter()
            .map(|node| {
                let key = node.key().unwrap();
                if let Some(&index) = old_key_to_old_index.get(&key) {
                    shared_keys.insert(key);
                    index
                } else {
                    u32::MAX as usize
                }
            })
            .collect::<Vec<_>>();
        // If none of the old keys are reused by the new children, then we remove all the remaining old children and
        // create the new children afresh.
        if shared_keys.is_empty() {
            if let Some(first_old) = old.get(0) {
                self.remove_nodes(&old[1..], true);
                self.stack
                    .create_children(new, MountType::Replace { old: first_old })
            } else {
                self.stack.create_children(new, MountType::Append {});
            }
            return;
        }
        // 4. Compute the LIS of this list
        let mut lis_sequence = Vec::default();
        lis_sequence.reserve(new_index_to_old_index.len());
        let mut predecessors = vec![0; new_index_to_old_index.len()];
        let mut starts = vec![0; new_index_to_old_index.len()];
        longest_increasing_subsequence::lis_with(
            &new_index_to_old_index,
            &mut lis_sequence,
            |a, b| a < b,
            &mut predecessors,
            &mut starts,
        );
        // the lis comes out backwards, I think. can't quite tell.
        lis_sequence.sort_unstable();
        // if a new node gets u32 max and is at the end, then it might be part of our LIS (because u32 max is a valid LIS)
        if lis_sequence.last().map(|f| new_index_to_old_index[*f]) == Some(u32::MAX as usize) {
            lis_sequence.pop();
        }
        let apply = |new_idx, new_node: &'bump VNode<'bump>, stack: &mut DiffStack<'bump>| {
            let old_index = new_index_to_old_index[new_idx];
            if old_index == u32::MAX as usize {
                stack.create_node(new_node, MountType::Absorb);
            } else {
                // this function should never take LIS indices
                stack.push(DiffInstruction::PrepareMove { node: new_node });
                stack.push(DiffInstruction::Diff {
                    new: new_node,
                    old: &old[old_index],
                });
            }
        };
        // add mount instruction for the last items not covered by the lis
        let first_lis = *lis_sequence.first().unwrap();
        if first_lis > 0 {
            self.stack.push_nodes_created(0);
            self.stack.push(DiffInstruction::Mount {
                and: MountType::InsertBefore {
                    other_node: &new[first_lis],
                },
            });
            for (idx, new_node) in new[..first_lis].iter().enumerate().rev() {
                apply(idx, new_node, &mut self.stack);
            }
        }
        // for each spacing, generate a mount instruction
        let mut lis_iter = lis_sequence.iter().rev();
        let mut last = *lis_iter.next().unwrap();
        for next in lis_iter {
            if last - next > 1 {
                self.stack.push_nodes_created(0);
                self.stack.push(DiffInstruction::Mount {
                    and: MountType::InsertBefore {
                        other_node: &new[last],
                    },
                });
                for (idx, new_node) in new[(next + 1)..last].iter().enumerate().rev() {
                    apply(idx + next + 1, new_node, &mut self.stack);
                }
            }
            last = *next;
        }
        // add mount instruction for the first items not covered by the lis
        let last = *lis_sequence.last().unwrap();
        if last < (new.len() - 1) {
            self.stack.push_nodes_created(0);
            self.stack.push(DiffInstruction::Mount {
                and: MountType::InsertAfter {
                    other_node: &new[last],
                },
            });
            for (idx, new_node) in new[(last + 1)..].iter().enumerate().rev() {
                apply(idx + last + 1, new_node, &mut self.stack);
            }
        }
        for idx in lis_sequence.iter().rev() {
            self.stack.push(DiffInstruction::Diff {
                new: &new[*idx],
                old: &old[new_index_to_old_index[*idx]],
            });
        }
    }
fn diff_keyed_middle ( & mut self , old : & ' bump [ VNode < ' bump > ] , new : & ' bump [ VNode < ' bump > ] ) { /*
        1. Map the old keys into a numerical ordering based on indices.
        2. Create a map of old key to its index
        3. Map each new key to the old key, carrying over the old index.
            - IE if we have ABCD becomes BACD, our sequence would be 1,0,2,3
            - if we have ABCD to ABDE, our sequence would be 0,1,3,MAX because E doesn't exist

        now, we should have a list of integers that indicates where in the old list the new items map to.

        4. Compute the LIS of this list
            - this indicates the longest list of new children that won't need to be moved.

        5. Identify which nodes need to be removed
        6. Identify which nodes will need to be diffed

        7. Going along each item in the new list, create it and insert it before the next closest item in the LIS.
            - if the item already existed, just move it to the right place.

        8. Finally, generate instructions to remove any old children.
        9. Generate instructions to finally diff children that are the same between both
        */ // 0. Debug sanity checks // Should have already diffed the shared-key prefixes and suffixes. debug_assert_ne ! ( new first ( ) map ( n n key ( ) ) old first ( ) map ( o o key ( ) ) ) ; debug_assert_ne ! ( new last ( ) map ( n n key ( ) ) old last ( ) map ( o o key ( ) ) ) ; // 1. Map the old keys into a numerical ordering based on indices. // 2. Create a map of old key to its index // IE if the keys were A B C, then we would have (A, 1) (B, 2) (C, 3). let old_key_to_old_index = old . iter ( ) . enumerate ( ) . map ( | ( i , o ) | ( o . key ( ) . unwrap ( ) , i ) ) . collect :: < FxHashMap < _ , _ > > ( ) ; let mut shared_keys = FxHashSet :: default ( ) ; // 3. Map each new key to the old key, carrying over the old index. let new_index_to_old_index = new . iter ( ) . map ( | node | { let key = node . key ( ) . unwrap ( ) ; if let Some ( & index ) = old_key_to_old_index . get ( & key ) { shared_keys . insert ( key ) ; index } else { u32 :: MAX as usize } } ) . collect :: < Vec < _ > > ( ) ; // If none of the old keys are reused by the new children, then we remove all the remaining old children and // create the new children afresh. if shared_keys . is_empty ( ) { if let Some ( first_old ) = old . get ( 0 ) { self . remove_nodes ( & old [ 1 .. ] , true ) ; self . stack . create_children ( new , MountType :: Replace { old : first_old } ) } else { self . stack . create_children ( new , MountType :: Append { } ) ; } return ; } // 4. Compute the LIS of this list let mut lis_sequence = Vec :: default ( ) ; lis_sequence . reserve ( new_index_to_old_index . len ( ) ) ; let mut predecessors = vec ! [ 0 new_index_to_old_index len ( ) ] ; let mut starts = vec ! [ 0 new_index_to_old_index len ( ) ] ; longest_increasing_subsequence :: lis_with ( & new_index_to_old_index , & mut lis_sequence , | a , b | a < b , & mut predecessors , & mut starts , ) ; // the lis comes out backwards, I think. can't quite tell. lis_sequence . sort_unstable ( ) ; // if a new node gets u32 max and is at the end, then it might be part of our LIS (because u32 max is a valid LIS) if lis_sequence . last ( ) . map ( | f | new_index_to_old_index [ * f ] ) == Some ( u32 :: MAX as usize ) { lis_sequence . pop ( ) ; } let apply = | new_idx , new_node : & ' bump VNode < ' bump > , stack : & mut DiffStack < ' bump > | { let old_index = new_index_to_old_index [ new_idx ] ; if old_index == u32 :: MAX as usize { stack . create_node ( new_node , MountType :: Absorb ) ; } else { // this function should never take LIS indices stack . push ( DiffInstruction :: PrepareMove { node : new_node } ) ; stack . push ( DiffInstruction :: Diff { new : new_node , old : & old [ old_index ] , } ) ; } } ; // add mount instruction for the last items not covered by the lis let first_lis = * lis_sequence . first ( ) . unwrap ( ) ; if first_lis > 0 { self . stack . push_nodes_created ( 0 ) ; self . stack . push ( DiffInstruction :: Mount { and : MountType :: InsertBefore { other_node : & new [ first_lis ] , } , } ) ; for ( idx , new_node ) in new [ .. first_lis ] . iter ( ) . enumerate ( ) . rev ( ) { apply ( idx , new_node , & mut self . stack ) ; } } // for each spacing, generate a mount instruction let mut lis_iter = lis_sequence . iter ( ) . rev ( ) ; let mut last = * lis_iter . next ( ) . unwrap ( ) ; for next in lis_iter { if last - next > 1 { self . stack . push_nodes_created ( 0 ) ; self . stack . push ( DiffInstruction :: Mount { and : MountType :: InsertBefore { other_node : & new [ last ] , } , } ) ; for ( idx , new_node ) in new [ ( next + 1 ) .. last ] . iter ( ) . enumerate ( ) . rev ( ) { apply ( idx + next + 1 , new_node , & mut self . stack ) ; } } last = * next ; } // add mount instruction for the first items not covered by the lis let last = * lis_sequence . last ( ) . unwrap ( ) ; if last < ( new . len ( ) - 1 ) { self . stack . push_nodes_created ( 0 ) ; self . stack . push ( DiffInstruction :: Mount { and : MountType :: InsertAfter { other_node : & new [ last ] , } , } ) ; for ( idx , new_node ) in new [ ( last + 1 ) .. ] . iter ( ) . enumerate ( ) . rev ( ) { apply ( idx + last + 1 , new_node , & mut self . stack ) ; } } for idx in lis_sequence . iter ( ) . rev ( ) { self . stack . push ( DiffInstruction :: Diff { new : & new [ * idx ] , old : & old [ new_index_to_old_index [ * idx ] ] , } ) ; } }
The most-general, expensive code path for keyed children diffing.
The most - general expensive code path for keyed children diffing .
&mut self
old
&'bump [VNode<'bump>]
new
&'bump [VNode<'bump>]