Please help me translate this C++ program into Rust (newbie questions)


#1

I’m trying to translate this C++ program into Rust, but I can’t seem to figure out the right way to reference my list nodes:

const int64_t N = 100000000;
const int64_t M = 10000000;

struct Node {
    Node* next = nullptr;
    int64_t a;
    int64_t b;
    int64_t c;

    Node(int64_t n) : a(n), b(n), c(n) {}
};

int main(int argc, const char * argv[]) {
    Node* head = new Node(0);
    Node* tail = head;
    system_clock::time_point t = system_clock::now();

    for (int64_t i = 1; true; ++i) {
        head->next = new Node(i);
        head = head->next;

        if (i > N) {
            Node* garbage = tail;
            tail = tail->next;
            delete garbage;
        }

        if (i % M == 0) {
            duration<double> elapsed = system_clock::now() - t;
            cout << elapsed.count() << " seconds\n";
            t = system_clock::now();
        }
    }
}

The Rust code I have so far doesn’t compile. I have a pretty good idea why it can’t work like this, but I’m not sure what would be a correct and idiomatic way to fix it:

use std::time::{Duration, Instant};

struct Node {
    next: Option<Box<Node>>,
    a: i64,
    b: i64,
    c: i64
}

impl Node {
    fn new(n: i64) -> Box<Node> {
        Box::new(Node{next: None, a: n, b: n, c: n})
    }
}

const N: i64 = 100000000;
const M: i64 = 10000000;

fn main() {
    let mut tail = Node::new(0);
    tail.next = Some(Node::new(1));
    let mut head = &mut tail.next.unwrap(); // ERROR: value moved here
    let mut t = Instant::now();
    let mut i = 2;

    loop {
        head.next = Some(Node::new(i));
        head = &mut head.next.unwrap(); // ERROR: cannot move out of borrowed content
        
        if i > N {
            tail = tail.next.unwrap(); // ERROR: use of moved value
        }

        if i % M == 0 {
            println!("{:?}", Instant::now() - t);
            t = Instant::now();
        }

        i += 1;
    }
}

The purpose of this program is to create some memory pressure and see how the memory management systems of various programming languages (or rather specific implementations) deal with it. It builds a singly linked list of N nodes and then keeps adding a node to the head and removing a node from the tail for all eternity.

I realise it would be polite to put more effort into learning Rust before asking for help here. I’m afraid impatience has gotten the better of me.

Thanks


#2

This could help you:

http://cglab.ca/~abeinges/blah/too-many-lists/book/


#3

Thanks, I will have a look.


#4

This version compiles, while adding one clone()

https://is.gd/bGI5I7


#5

Thanks, it compiles!

Unfortunately, cloning the tail node means that tail is no longer connected to head and therefore the program panics at the point where I’m trying move along the tail pointer, thereby deleting the previous tail node:

    if i > N {
        tail = tail.next.unwrap();
    }

I sort of doubt that this line would work as intended even without the panic caused by clone though.


#6

May be this can help: http://cglab.ca/~abeinges/blah/too-many-lists/book/README.html