Skip to content

Instantly share code, notes, and snippets.

@dminuoso
Last active June 8, 2018 08:52
Show Gist options
  • Save dminuoso/9f1553de67a933410239c702a5b8b4f7 to your computer and use it in GitHub Desktop.
Save dminuoso/9f1553de67a933410239c702a5b8b4f7 to your computer and use it in GitHub Desktop.
require 'concurrent'
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)
as.push(a)
t.write(@write, as)
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
y, *ys_ = ys
t.write(@write, [])
t.write(@read, ys_)
return y
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, xs.unshift(a)
return nil
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