Skip to content

Instantly share code, notes, and snippets.

@mkweick
Last active January 23, 2016 16:26
Show Gist options
  • Save mkweick/fbbd0f565a707ab72aab to your computer and use it in GitHub Desktop.
Save mkweick/fbbd0f565a707ab72aab to your computer and use it in GitHub Desktop.
Circular Buffer
class CircularBuffer
class BufferEmptyException < StandardError; end
class BufferFullException < StandardError; end
attr_reader :buffer, :buffer_size
attr_accessor :read_id, :write_id
def initialize(buffer_size)
@buffer = []
@buffer_size = buffer_size
@read_id = 1
@write_id = 1
buffer_size.times { |n| buffer << Element.new(n + 1) }
end
def read
read_validation
value = element(read_id).value
element(read_id).clear
rotate_read_id
value
end
def write(value)
return if value.nil?
write_validation
element(write_id).value = value
rotate_write_id
end
def write!(value)
if value && full?
element(write_id).clear
rotate_read_id
end
write(value)
end
def clear
buffer.each { |element| element.value = nil }
end
private
def empty?
buffer.all? { |element| element.value.nil? }
end
def full?
buffer.none? { |element| element.value.nil? }
end
def element(id)
buffer.find { |element| element.id == id }
end
def rotate_read_id
read_id == buffer_size ? (self.read_id = 1) : (self.read_id += 1)
end
def rotate_write_id
write_id == buffer_size ? (self.write_id = 1) : (self.write_id += 1)
end
def read_validation
fail BufferEmptyException if empty?
end
def write_validation
fail BufferFullException if full?
end
end
class Element
attr_reader :id
attr_accessor :value
def initialize(id)
@id = id
@value = nil
end
def clear
self.value = nil
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment