v icon indicating copy to clipboard operation
v copied to clipboard

datatypes: adding ringbuffer

Open floscodes opened this issue 2 years ago • 18 comments

Rewritten ringbuffer-feature moved to vlib/datatypes. Implementing head and tail pointers, as well as fixed sized array

Example:

module main

import datatypes

fn main() {

    // create a new ringbuffer with size 4
    // the generic argument sets the type
    mut r := datatypes.new_ringbuffer<int>(4)

    // push elements
    r.push(3)
    r.push(4)

    // get the oldest element. It will be removed from the buffer when calling `pop()`
    oldest_value := r.pop()

    println(oldest_value) // Output: 3

    }

floscodes avatar Sep 19 '22 10:09 floscodes

Done.

floscodes avatar Sep 19 '22 13:09 floscodes

I added errors now and implemented the suggested changes.

floscodes avatar Sep 20 '22 08:09 floscodes

Thank you. I just need ringbuffer.

Can you provide a method to push more elements at a time? push(elements []T) This is very useful for reading and writing socket buffers. Reading and writing one by one a byte cumbersome and slow

shove70 avatar Sep 20 '22 09:09 shove70

Thank you. I just need ringbuffer.

Can you provide a method to push more elements at a time? push(elements []T) This is very useful for reading and writing socket buffers. Reading and writing one by one a byte cumbersome and slow

Won't push_many(elements []T) method be better?

Delta456 avatar Sep 20 '22 09:09 Delta456

Good idea, will work on it.

floscodes avatar Sep 20 '22 10:09 floscodes

It may be even better to simply implement push(elements ...T). Then you can supply 1 or more elements. If you want to only push 1, it would be push(one). To push 2, push(one, two). If you want to push an array, it would be push(...arr).

You can even go crazy with something like push(one, two, ...arr, three, four).

JalonSolov avatar Sep 20 '22 13:09 JalonSolov

It may be even better to simply implement push(elements ...T). Then you can supply 1 or more elements. If you want to only push 1, it would be push(one). To push 2, push(one, two). If you want to push an array, it would be push(...arr).

You can even go crazy with something like push(one, two, ...arr, three, four).

Strongly agree

shove70 avatar Sep 20 '22 13:09 shove70

It may be even better to simply implement push(elements ...T). Then you can supply 1 or more elements. If you want to only push 1, it would be push(one). To push 2, push(one, two). If you want to push an array, it would be push(...arr).

You can even go crazy with something like push(one, two, ...arr, three, four).

I also agree. Have to change it now, first I did push_many. Will change it.

floscodes avatar Sep 20 '22 14:09 floscodes

I see you also have pop and pop_many. Maybe just pop that always returns an array? Not sure about that one. Less convenient if you only want to pop one thing, but consistent...

JalonSolov avatar Sep 20 '22 14:09 JalonSolov

I see you also have pop and pop_many. Maybe just pop that always returns an array? Not sure about that one. Less convenient if you only want to pop one thing, but consistent...

Yes, I have also been thinking about it. I could do pop(n ...u64) allowing only one n element in the array to be given. If n.len equals 0 or the value of the first element equals 1, it would return a single element, otherwise it would return an array... What do you think?

edit

… but that wouldn’t be possible since I have to choose whether a method returns T or []T

floscodes avatar Sep 20 '22 14:09 floscodes

I tried to do it like push(elements ...T), but I get a builder error when trying it out... I don't know why. See below...

/tmp/v_501/ring.15083904507890574193.tmp.c:12164:131: error: initializing 'int' with an expression of incompatible type 'Array_int' (aka 'struct array')
        _option_void _t1 = ringbuffer__RingBuffer_T_int_push_T_int(&ring, new_array_from_c_array_noscan(1, 1, sizeof(int), _MOV((int[1]){_v_array})));
                                                                                                                                         ^~~~~~~~
1 warning and 1 error generated.
...
==================
(Use `v -cg` to print the entire error message)

builder error: 
==================
C error. This should never happen.

floscodes avatar Sep 20 '22 15:09 floscodes

For now I will leave it like this with two separate methodspush(element T) and push_many(elements []T).

This solution works.

floscodes avatar Sep 20 '22 15:09 floscodes

I tried to do it like push(elements ...T), but I get a builder error when trying it out... I don't know why. See below...

When you receive it, it will look like an array. You have to do the for e in elements that you have in push_many.

JalonSolov avatar Sep 20 '22 15:09 JalonSolov

I tried to do it like push(elements ...T), but I get a builder error when trying it out... I don't know why. See below...

When you receive it, it will look like an array. You have to do the for e in elements that you have in push_many.

Yes, this is what I did. It gives me the error above...

floscodes avatar Sep 20 '22 15:09 floscodes

Good work @floscodes

larpon avatar Sep 20 '22 16:09 larpon

Good work @floscodes

Thank you 🙏

floscodes avatar Sep 20 '22 17:09 floscodes

The failing macos-cross job is because of network errors. I'll try and re-run it edit Looks like we're all green :)

larpon avatar Sep 21 '22 06:09 larpon

The failing macos-cross job is because of network errors.

I'll try and re-run it

edit

Looks like we're all green :)

.... oh that's why 😅 thank you!

floscodes avatar Sep 21 '22 08:09 floscodes

Good work.

Thank you 🙏

floscodes avatar Sep 21 '22 16:09 floscodes