Closed xbeta closed 9 years ago
@xbeta: This is intended. To quote from the README:
Hamster collections are immutable. Whenever you modify a Hamster collection, the original is preserved and a modified copy is returned. This makes them inherently thread-safe and shareable. At the same time, they remain CPU and memory-efficient by sharing between copies.
This is true for all Hamster's data structures: Hamster::Hash
, Hamster::Vector
, and so on. So a #push
or a #set
on a Hamster::Vector
instance will return a new one, unlike Ruby's built-in Array
which will modify the instance in-place.
In any case, @xbeta, thank you for your interest in Hamster! (And thanks to @dubek for explaining things.) If you need a mutable queue, I suggest you use the one in the Ruby standard library.
@dubek thanks for the explanation, but what's stopping one thread push()
and another thread pop()
at the same time in a concurrency world?
def initialize()
@nums = Hamster::Deque.new()
end
..
def add(num)
# because hamster's deque is immutable
@nums = @nums.push(num)
end
@xbeta, nothing is stopping 2 threads from doing those things at the same time. You can "stop" them by locking, just the same as with a mutable queue. Or, you have another option, which doesn't exist with a mutable queue: you can retry an atomic compare-and-swap until it succeeds. Or, your queue might exist only on the stack of one thread, meaning it can never be shared with another thread.
I read this in the API doc that it returns a new Deque in every
push()
, instead of a reusing the same Deque and perform an in-place change. Why is this behavior even consider to be implemented???The stdlib ruby core Queue doesn't have that behavior.