-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcircular_buffer_ruby.rb
64 lines (51 loc) · 1.53 KB
/
circular_buffer_ruby.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# Ruby implementation of circular buffer backed by an array. A circular buffer
# is a buffer of a finite size with a read and write cursor. When the
# read or write cursor reaches the end of the buffer, it wraps around to
# the beginning again.
# See: https://en.wikipedia.org/wiki/Circular_buffer
class CircularBufferRuby
# Initializes the circular buffer.
#
# @param capacity [Integer] the capacity of the circular buffer
def initialize(capacity)
@buffer = Array.new(capacity)
@length = 0
@read_cursor = 0
@write_cursor = 0
end
# Writes an object to the circular buffer at the current write cursor and
# moves the write cursor forward. Raises if the buffer is full.
#
# @param obj [Object] the object to write to the circular buffer
# @return the object written
def write(obj)
raise "Circular buffer is full" if full?
@buffer[@write_cursor] = obj
# Advance write_cursor
@write_cursor = next_cursor_position(@write_cursor)
@length += 1
obj
end
# Reads the object in the circular buffer at the current read cursor and
# moves the read cursor forward. Raises if the buffer is empty.
#
# @return the object read
def read
raise "Circular buffer is empty" if empty?
obj = @buffer[@read_cursor]
# Advance read_cursor
@read_cursor = next_cursor_position(@read_cursor)
@length -= 1
obj
end
private
def next_cursor_position(cursor)
(cursor + 1) % @buffer.length
end
def full?
@length == @buffer.length
end
def empty?
@length == 0
end
end