Removing a node from rendezvous_hash::RendezvousNodes in Rust

57 Views Asked by At

I am trying to remove a node from the RendezvousNodes collection of the rendezvous_hash crate.

The shortened example code I am using is:

use std::collections::HashMap;
use rendezvous_hash::{RendezvousNodes, Node};
use rendezvous_hash::{WeightedNode, Capacity};

fn main() {
    let mut nodes = RendezvousNodes::default();


    let node1 = WeightedNode::new("foo", Capacity::new(70.0).unwrap());
    nodes.insert(node1);
    println!("{}", nodes.len());

    for node in nodes.iter() {
        println!("{}", node.node_id());
    }

    nodes.remove(node1.node_id());
    println!("{}", nodes.len());
}

This fails because of value borrowed after move.

error[E0382]: borrow of moved value: `node1`
  --> src/main.rs:17:18
   |
9  |     let node1 = WeightedNode::new("foo", Capacity::new(70.0).unwrap());
   |         ----- move occurs because `node1` has type `WeightedNode<&str>`, which does not implement the `Copy` trait
10 |     nodes.insert(node1);
   |                  ----- value moved here
...
17 |     nodes.remove(node1.node_id());
   |                  ^^^^^ value borrowed here after move

Passing in a reference for node works:

...
    nodes.insert(&node1);
...

However, now I have to keep track of the node value myself which I do not want, and it likely creates later problems with scope and lifetime. It should be sufficient to have the nodes collection keeping track of its nodes.

Is there a way to remove the node though it is owned by nodes now, or is this a problem of the crate?

1

There are 1 best solutions below

0
Johannes Maria Frank On BEST ANSWER

By reading the source for the remove method:

/// Removes the specified node from the candidates.
    ///
    /// If the node does not exist, this method will return `None`.
    pub fn remove<M>(&mut self, node_id: &M) -> Option<N>
    where
        N::NodeId: Borrow<M>,
        M: PartialEq,
    {
        if let Some(i) = self
            .nodes
            .iter()
            .position(|n| n.node_id().borrow() == node_id)
        {
            Some(self.nodes.swap_remove(i))
        } else {
            None
        }
    }

from

docs.rs

it gets clear that passing a reference to the node_id does it.

nodes.remove(&"foo");

EDIT:

And if I had read the docs more thoroughly, I would probably have spotted:

// Update the node set.
// (The relative order between existing nodes are preserved)
nodes.remove(&"baz");