Tony
Tony

Reputation: 19181

How do I insert into or update an RBTree from rbtree-rs?

I'm having trouble understanding how to idiomatically find and append to or create a new vector if the value is part of a data structure, in this case a Red Black tree.

I'm using this Red Black Tree implementation and the plan is to grab a mutable reference to the value which I will append to if it exists (not None) and create a new vector and move it to the RBTree if there is no value for the key. My code looks like this, slightly altered for brevity so excuse any careless errors:

struct Obj {
    tree: RBTree<i32, Vec<String>>,
}

let mut obj = Obj {
    tree: RBTree::new(),
};

let k = 5;
let v = "whatever";

match obj.tree.get_mut(k) {
    None => {
        let mut vec: Vec<Node> = Vec::new();
        vec.push(v);
        book.tree.insert(k, vec);
    }
    Some(vec) => vec.push(v),
}

The problem is that I'm getting a mutable reference to the tree when I check for existence because if it does exist, I want to mutate it by appending to the vector. However, if it does not exist, I want to insert a new node which tries to do a mutable borrow so I get a "second mutable borrow occurs here" on this line book.tree.insert(k, vec);.

I would love some insight into how to perform this find or create so that it compiles and is thread safe. I guess it's also possible the library I'm using has problems. Not yet qualified to comment on that.

Upvotes: 0

Views: 142

Answers (1)

Kornel
Kornel

Reputation: 100180

In such cases the workaround is to move the mutating code outside of get_mut()'s scope.

let needs_insert = match obj.tree.get_mut(k) {
    None => true,
    Some(vec) => {
        vec.push(v); 
        false
    }
};

if needs_insert {
    book.tree.insert(k, vec![v]);
}

Upvotes: 0

Related Questions