Skip to content

Instantly share code, notes, and snippets.

@benolee
Forked from dminuoso/tbqueue.rb
Created February 4, 2019 21:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benolee/471fa02bb287b7a1a4a67308dde82035 to your computer and use it in GitHub Desktop.
Save benolee/471fa02bb287b7a1a4a67308dde82035 to your computer and use it in GitHub Desktop.
class TBQueue
def initialize size
tvar = Concurrent::TVar
@read = tvar.new []
@write = tvar.new []
@rsize = tvar.new 0
@wsize = tvar.new size
end
def write(a)
w = t.read(@wsize)
if w != 0
t.write(@wsize, w - 1)
else
r = t.read(@rsize)
if r != 0
t.write(@rsize, 0)
t.write(@wsize, r - 1)
else
retry_transaction
end
end
as = t.read(@write)
t.write(@write, [*as, a])
return nil
end
def read
xs = t.read(@read)
r = t.read(@rsize)
t.write(@rsize, r + 1)
if !xs.empty?
x, *xs_ = xs
t.write(@read, xs_)
return x
else
ys = t.read(@write)
if ys.empty?
retry_transaction
else
z, *zs = ys
t.write(@write, [])
t.write(@read, zs)
return z
end
end
end
def peek
x = read
unshift x
return x
end
def unget a
r = t.read @rsize
if r > 0
t.write @rsize, r - 1
else
w = t.read @wsize
if w > 0
t.write @wsize, w - 1
else
retry_transaction
end
end
xs = t.read @read
t.write @read, [a, *xs]
return nil
end
def empty?
xs = t.read @read
if xs.empty?
ys = t.read @write
return ys.empty?
else
return false
end
end
private
def t
Concurrent::Transaction.current
end
def retry_transaction
Concurrent.abort_transaction
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment