fn modify_helper(
        &mut self,
        r_node: &NodeId,
        key: &ADKey,
        operation: &Operation,
    ) -> Result<(
        NodeId,
        ChangeHappened,
        HeightIncreased,
        ToDelete,
        Option<ADValue>,
    )> {
        // Do not set the visited flag on the way down -- set it only after you know the operation did not fail,
        // because if the operation failed, there is no need to put nodes in the proof.
        let res = match self.tree().copy(r_node) {
			Node::Leaf(r) => {
                if self.key_matches_leaf(key, &r)? {
                    match operation {
                        Operation::Lookup(_) => {
                            self.on_node_visit(r_node, operation, false);
                            (r_node.clone(), false, false, false, Some(r.value))
                        }
                        _ => { // on modification
                            match operation.update_fn(Some(r.value.clone()))? {
                                None =>  { // delete key
                                    self.on_node_visit(r_node, operation, false);
                                    (r_node.clone(), false, false, true, Some(r.value))
                                }
                                Some(v) => { // update value
                                    assert!(self.tree().value_length.filter(|len|v.len() != *len).is_none());
                                    let old_value = Some(r.value);
                                    let r_new = LeafNode::update(r_node, &r.hdr.key.unwrap(), &v, &r.next_node_key);
                                    self.on_node_visit(r_node, operation, false);
                                    (r_new, true, false, false, old_value)
                                }
                            }
                        } // do nothing
                    }
                } else {
                    // x > r.key
                    match operation {
                        Operation::Lookup(_) => {
                            self.on_node_visit(r_node, operation, false);
                            (r_node.clone(), false, false, false, None)
                        }
                        _ => { // on modification
                            match operation.update_fn(None)? {
                                None => { // don't change anything, just lookup
                                    self.on_node_visit(r_node, operation, false);
                                    (r_node.clone(), false, false, false, None)
                                }
                                Some(v) => { // insert new value
                                    assert!(self.tree().value_length.filter(|len|v.len() != *len).is_none());
                                    self.on_node_visit(r_node, operation, false);
                                    (self.add_node(r_node, &key, &v), true, true, false, None)
                                }
                            }
                        }
                    }
                }
            }
            Node::Internal(r) => {
                // Go recursively in the correct direction
                // Get a new node
                // See if a single or double rotation is needed for AVL tree balancing
                if self.next_direction_is_left(key, &r) {
                    let (new_leftm, change_happened, child_height_increased, to_delete, old_value) = self.modify_helper(&r.left, key, operation)?;
                    self.on_node_visit(r_node, operation, false);

                    // balance = -1 if left higher, +1 if left lower
                    if change_happened {
                        if child_height_increased && r.balance < 0 {
                            // need to rotate
                            // at this point we know newLeftM must be an internal node and not a leaf -- because height increased
                            if self.tree().balance(&new_leftm) < 0 {
                                // single right rotate
                                let new_r = InternalNode::update(r_node, &self.tree().right(&new_leftm), &r.right, 0);
                                (InternalNode::update(&new_leftm, &self.tree().left(&new_leftm), &new_r, 0), true, false, false, old_value)
                            } else {
                                (self.double_right_rotate(r_node, &new_leftm, &r.right), true, false, false, old_value)
                            }
                        } else {
                            // no need to rotate
                            let my_height_increased = child_height_increased && r.balance == 0;
                            let r_balance = if child_height_increased { r.balance - 1 } else { r.balance };
                            (InternalNode::update(r_node, &new_leftm, &r.right, r_balance), true, my_height_increased, false, old_value)
                        }
                    } else {
                        // no change happened
                        (r_node.clone(), false, false, to_delete, old_value)
                    }
                } else {
                    let (new_rightm, change_happened, child_height_increased, to_delete, old_value) = self.modify_helper(&r.right, key, operation)?;
                    self.on_node_visit(r_node, operation, false);

                    // balance = -1 if left higher, +1 if left lower
                    if change_happened {
                        if child_height_increased && r.balance > 0 {
                            // need to rotate
                            // at this point we know newRightM must be an internal node and not a leaf -- because height increased
                            if self.tree().balance(&new_rightm) > 0 {
                                // single left rotate
                                let new_r = InternalNode::update(r_node, &r.left, &self.tree().left(&new_rightm), 0);
                                (InternalNode::update(&new_rightm, &new_r, &self.tree().right(&new_rightm), 0), true, false, false, old_value)
                            } else {
                                (self.double_left_rotate(r_node, &r.left, &new_rightm), true, false, false, old_value)
                            }
                        } else {
                            // no need to rotate
                            let my_height_increased = child_height_increased && r.balance == 0;
                            let r_balance = if child_height_increased { r.balance + 1 } else { r.balance };
                            (InternalNode::update(r_node, &r.left, &new_rightm, r_balance), true, my_height_increased, false, old_value)
                        }
                    } else {
                        // no change happened
                        (r_node.clone(), false, false, to_delete, old_value)
                    }
                }
            }
            _ =>
                bail!("Should never reach this point. If in prover, this is a bug. If in verifier, this proof is wrong.")
        };
        Ok(res)
    }
///
/// returns the new root, an indicator whether tree has been modified at r or below,
/// an indicator whether the height has increased,
/// an indicator whether we need to go delete the leaf that was just reached,
/// and the old value associated with key
///
/// Handles binary tree search and AVL rebalancing
///
/// Deletions are not handled here in order not to complicate the code even more -- in case of deletion,
/// we don't change the tree, but simply return toDelete = true.
/// We then go in and delete using deleteHelper
///
returns the new root, an indicator whether tree has been modified at r or below,
an indicator whether the height has increased,
an indicator whether we need to go delete the leaf that was just reached,
and the old value associated with key

Handles binary tree search and AVL rebalancing

Deletions are not handled here in order not to complicate the code even more -- in case of deletion,
we don't change the tree, but simply return toDelete = true.
We then go in and delete using deleteHelper
returns the new root an indicator whether tree has been modified at r or below an indicator whether the height has increased an indicator whether we need to go delete the leaf that was just reached and the old value associated with key Handles binary tree search and AVL rebalancing Deletions are not handled here in order not to complicate the code even more -- in case of deletion we don ' t change the tree but simply return toDelete = true . We then go in and delete using deleteHelper
fn modify_helper(
        &mut self,
        r_node: &NodeId,
        key: &ADKey,
        operation: &Operation,
    ) -> Result<(
        NodeId,
        ChangeHappened,
        HeightIncreased,
        ToDelete,
        Option<ADValue>,
    )> {
        // Do not set the visited flag on the way down -- set it only after you know the operation did not fail,
        // because if the operation failed, there is no need to put nodes in the proof.
        let res = match self.tree().copy(r_node) {
			Node::Leaf(r) => {
                if self.key_matches_leaf(key, &r)? {
                    match operation {
                        Operation::Lookup(_) => {
                            self.on_node_visit(r_node, operation, false);
                            (r_node.clone(), false, false, false, Some(r.value))
                        }
                        _ => { // on modification
                            match operation.update_fn(Some(r.value.clone()))? {
                                None =>  { // delete key
                                    self.on_node_visit(r_node, operation, false);
                                    (r_node.clone(), false, false, true, Some(r.value))
                                }
                                Some(v) => { // update value
                                    assert!(self.tree().value_length.filter(|len|v.len() != *len).is_none());
                                    let old_value = Some(r.value);
                                    let r_new = LeafNode::update(r_node, &r.hdr.key.unwrap(), &v, &r.next_node_key);
                                    self.on_node_visit(r_node, operation, false);
                                    (r_new, true, false, false, old_value)
                                }
                            }
                        } // do nothing
                    }
                } else {
                    // x > r.key
                    match operation {
                        Operation::Lookup(_) => {
                            self.on_node_visit(r_node, operation, false);
                            (r_node.clone(), false, false, false, None)
                        }
                        _ => { // on modification
                            match operation.update_fn(None)? {
                                None => { // don't change anything, just lookup
                                    self.on_node_visit(r_node, operation, false);
                                    (r_node.clone(), false, false, false, None)
                                }
                                Some(v) => { // insert new value
                                    assert!(self.tree().value_length.filter(|len|v.len() != *len).is_none());
                                    self.on_node_visit(r_node, operation, false);
                                    (self.add_node(r_node, &key, &v), true, true, false, None)
                                }
                            }
                        }
                    }
                }
            }
            Node::Internal(r) => {
                // Go recursively in the correct direction
                // Get a new node
                // See if a single or double rotation is needed for AVL tree balancing
                if self.next_direction_is_left(key, &r) {
                    let (new_leftm, change_happened, child_height_increased, to_delete, old_value) = self.modify_helper(&r.left, key, operation)?;
                    self.on_node_visit(r_node, operation, false);
                    // balance = -1 if left higher, +1 if left lower
                    if change_happened {
                        if child_height_increased && r.balance < 0 {
                            // need to rotate
                            // at this point we know newLeftM must be an internal node and not a leaf -- because height increased
                            if self.tree().balance(&new_leftm) < 0 {
                                // single right rotate
                                let new_r = InternalNode::update(r_node, &self.tree().right(&new_leftm), &r.right, 0);
                                (InternalNode::update(&new_leftm, &self.tree().left(&new_leftm), &new_r, 0), true, false, false, old_value)
                            } else {
                                (self.double_right_rotate(r_node, &new_leftm, &r.right), true, false, false, old_value)
                            }
                        } else {
                            // no need to rotate
                            let my_height_increased = child_height_increased && r.balance == 0;
                            let r_balance = if child_height_increased { r.balance - 1 } else { r.balance };
                            (InternalNode::update(r_node, &new_leftm, &r.right, r_balance), true, my_height_increased, false, old_value)
                        }
                    } else {
                        // no change happened
                        (r_node.clone(), false, false, to_delete, old_value)
                    }
                } else {
                    let (new_rightm, change_happened, child_height_increased, to_delete, old_value) = self.modify_helper(&r.right, key, operation)?;
                    self.on_node_visit(r_node, operation, false);
                    // balance = -1 if left higher, +1 if left lower
                    if change_happened {
                        if child_height_increased && r.balance > 0 {
                            // need to rotate
                            // at this point we know newRightM must be an internal node and not a leaf -- because height increased
                            if self.tree().balance(&new_rightm) > 0 {
                                // single left rotate
                                let new_r = InternalNode::update(r_node, &r.left, &self.tree().left(&new_rightm), 0);
                                (InternalNode::update(&new_rightm, &new_r, &self.tree().right(&new_rightm), 0), true, false, false, old_value)
                            } else {
                                (self.double_left_rotate(r_node, &r.left, &new_rightm), true, false, false, old_value)
                            }
                        } else {
                            // no need to rotate
                            let my_height_increased = child_height_increased && r.balance == 0;
                            let r_balance = if child_height_increased { r.balance + 1 } else { r.balance };
                            (InternalNode::update(r_node, &r.left, &new_rightm, r_balance), true, my_height_increased, false, old_value)
                        }
                    } else {
                        // no change happened
                        (r_node.clone(), false, false, to_delete, old_value)
                    }
                }
            }
            _ =>
                bail!("Should never reach this point. If in prover, this is a bug. If in verifier, this proof is wrong.")
        };
        Ok(res)
    }
fn modify_helper ( & mut self , r_node : & NodeId , key : & ADKey , operation : & Operation , ) -> Result < ( NodeId , ChangeHappened , HeightIncreased , ToDelete , Option < ADValue > , ) > { // Do not set the visited flag on the way down -- set it only after you know the operation did not fail, // because if the operation failed, there is no need to put nodes in the proof. let res = match self . tree ( ) . copy ( r_node ) { Node :: Leaf ( r ) => { if self . key_matches_leaf ( key , & r ) ? { match operation { Operation :: Lookup ( _ ) => { self . on_node_visit ( r_node , operation , false ) ; ( r_node . clone ( ) , false , false , false , Some ( r . value ) ) } _ => { // on modification match operation . update_fn ( Some ( r . value . clone ( ) ) ) ? { None => { // delete key self . on_node_visit ( r_node , operation , false ) ; ( r_node . clone ( ) , false , false , true , Some ( r . value ) ) } Some ( v ) => { // update value assert ! ( self tree ( ) value_length filter ( len v len ( ) len ) is_none ( ) ) ; let old_value = Some ( r . value ) ; let r_new = LeafNode :: update ( r_node , & r . hdr . key . unwrap ( ) , & v , & r . next_node_key ) ; self . on_node_visit ( r_node , operation , false ) ; ( r_new , true , false , false , old_value ) } } } // do nothing } } else { // x > r.key match operation { Operation :: Lookup ( _ ) => { self . on_node_visit ( r_node , operation , false ) ; ( r_node . clone ( ) , false , false , false , None ) } _ => { // on modification match operation . update_fn ( None ) ? { None => { // don't change anything, just lookup self . on_node_visit ( r_node , operation , false ) ; ( r_node . clone ( ) , false , false , false , None ) } Some ( v ) => { // insert new value assert ! ( self tree ( ) value_length filter ( len v len ( ) len ) is_none ( ) ) ; self . on_node_visit ( r_node , operation , false ) ; ( self . add_node ( r_node , & key , & v ) , true , true , false , None ) } } } } } } Node :: Internal ( r ) => { // Go recursively in the correct direction // Get a new node // See if a single or double rotation is needed for AVL tree balancing if self . next_direction_is_left ( key , & r ) { let ( new_leftm , change_happened , child_height_increased , to_delete , old_value ) = self . modify_helper ( & r . left , key , operation ) ? ; self . on_node_visit ( r_node , operation , false ) ; // balance = -1 if left higher, +1 if left lower if change_happened { if child_height_increased && r . balance < 0 { // need to rotate // at this point we know newLeftM must be an internal node and not a leaf -- because height increased if self . tree ( ) . balance ( & new_leftm ) < 0 { // single right rotate let new_r = InternalNode :: update ( r_node , & self . tree ( ) . right ( & new_leftm ) , & r . right , 0 ) ; ( InternalNode :: update ( & new_leftm , & self . tree ( ) . left ( & new_leftm ) , & new_r , 0 ) , true , false , false , old_value ) } else { ( self . double_right_rotate ( r_node , & new_leftm , & r . right ) , true , false , false , old_value ) } } else { // no need to rotate let my_height_increased = child_height_increased && r . balance == 0 ; let r_balance = if child_height_increased { r . balance - 1 } else { r . balance } ; ( InternalNode :: update ( r_node , & new_leftm , & r . right , r_balance ) , true , my_height_increased , false , old_value ) } } else { // no change happened ( r_node . clone ( ) , false , false , to_delete , old_value ) } } else { let ( new_rightm , change_happened , child_height_increased , to_delete , old_value ) = self . modify_helper ( & r . right , key , operation ) ? ; self . on_node_visit ( r_node , operation , false ) ; // balance = -1 if left higher, +1 if left lower if change_happened { if child_height_increased && r . balance > 0 { // need to rotate // at this point we know newRightM must be an internal node and not a leaf -- because height increased if self . tree ( ) . balance ( & new_rightm ) > 0 { // single left rotate let new_r = InternalNode :: update ( r_node , & r . left , & self . tree ( ) . left ( & new_rightm ) , 0 ) ; ( InternalNode :: update ( & new_rightm , & new_r , & self . tree ( ) . right ( & new_rightm ) , 0 ) , true , false , false , old_value ) } else { ( self . double_left_rotate ( r_node , & r . left , & new_rightm ) , true , false , false , old_value ) } } else { // no need to rotate let my_height_increased = child_height_increased && r . balance == 0 ; let r_balance = if child_height_increased { r . balance + 1 } else { r . balance } ; ( InternalNode :: update ( r_node , & r . left , & new_rightm , r_balance ) , true , my_height_increased , false , old_value ) } } else { // no change happened ( r_node . clone ( ) , false , false , to_delete , old_value ) } } } _ => bail ! ( " " ) } ; Ok ( res ) }
returns the new root, an indicator whether tree has been modified at r or below,
an indicator whether the height has increased,
an indicator whether we need to go delete the leaf that was just reached,
and the old value associated with key
returns the new root an indicator whether tree has been modified at r or below an indicator whether the height has increased an indicator whether we need to go delete the leaf that was just reached and the old value associated with key
&mut self
r_node
&NodeId
key
&ADKey
operation
&Operation
&mut self
r_node
&NodeId
key
&ADKey
operation
&Operation