Use case clarification #121
-
The example in the docs show reading and writing from the same function, but I'd expect the typical use case for a ring buffer to be separate producer and consumer thread/tasks. Since the read and write methods require mutable, it's not clear how this could be used in this situation. I could wrap it in Am I misreading the use case (producer/consumer with time guarantees)? If not, out of curiosity, what is the typical use case for this? Or is there some way to do this I missed. I couldn't find any relevant examples or benchmark. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 6 replies
-
You are right that reading and writing from two places in the program requires some kind of synchronization primitive. Indeed, ringbuffer does not aim to be inherently thread-safe, like some other ringbuffers might be. Often such implementations use atomics, and this is something we do not do and decided we will never do. It turns out that that's essentially a completely different data structure. So what can ringbuffer be used for? We've seen it be used in a wide range of situations. One example I've seen many times is if there's some stream of data coming in, and you care only about storing the last n bytes. We've seen people use it as part of decompression algorithms, where the compressed data could refer to an offset in the last kilobyte of data. Ringbuffer can also be useful in embedded contexts. Instead of a true mutex, you would rely on turning off interrupts while items are removed. Maybe when keyboard inputs are given and they should be sent from interrupt handlers to the main kernel. Both of us maintainers are currently teaching Computer Science at the Delft University of Technology, and in some of the courses we've had this exact usecase when writing template code for students to continue on. Our original use case was for a kind of public online whiteboard. We wanted old drawings to disappear automatically, so the server would put drawn points in a large ringbuffer and after a while the capacity was reached and old points would disappear automatically. Initially this was a sort of hobby project until we realized such a ringbuffer didn't really exist at the time. Some of these applications can also be solved by VecDeque, indeed we have a GrowableRingbuffer type that's internally simply a VecDeque. However, with VecDeque the maximum size cannot be fixed. Furthermore, VecDeques require allocation and we do not always, we have the ConstGenericRingbuffer which I've found I'm using most. In your case, if you'd like to refer to a ringbuffer on different places in the program whole still being single threaded, a more performant option might be (Rc) RefCell. I do think it's important we write more of this story down, so I appreciate your question a lot. We should keep this issue open until we've put something like this in the Readme. In the meantime, feel free to ask any question you like :) |
Beta Was this translation helpful? Give feedback.
You are right that reading and writing from two places in the program requires some kind of synchronization primitive. Indeed, ringbuffer does not aim to be inherently thread-safe, like some other ringbuffers might be. Often such implementations use atomics, and this is something we do not do and decided we will never do. It turns out that that's essentially a completely different data structure.
So what can ringbuffer be used for? We've seen it be used in a wide range of situations. One example I've seen many times is if there's some stream of data coming in, and you care only about storing the last n bytes. We've seen people use it as part of decompression algorithms, where the compress…