class Expeditor::RingBuffer
Circular buffer with user-defined initialization and optimized `move` implementation. The next element will be always initialized with user-defined initialization proc.
Thread unsafe.
Public Class Methods
@params [Integer] size
# File lib/expeditor/ring_buffer.rb, line 9 def initialize(size, &initialize_proc) raise ArgumentError.new('initialize_proc is not given') unless initialize_proc @size = size @initialize_proc = initialize_proc @elements = Array.new(@size, &initialize_proc) @current_index = 0 end
Public Instance Methods
@return [Array<Object>] Array of elements.
# File lib/expeditor/ring_buffer.rb, line 31 def all @elements end
@return [Object] user created object with given initialization proc.
# File lib/expeditor/ring_buffer.rb, line 18 def current @elements[@current_index] end
@params [Integer] times How many elements will we pass. @return [Object] current element after moving.
# File lib/expeditor/ring_buffer.rb, line 24 def move(times) cut_moving_time_if_possible(times).times do next_element end end
Private Instance Methods
This logic is used for cutting moving times. When moving times is greater than statuses size, we can cut moving times to less than statuses size because the statuses are circulated.
`*` is current index. When the statuses size is 3:
[*, , ]
Then when the moving times = 3, current index will be 0 (0-origin):
[*, , ] -3> [ ,*, ] -2> [ , ,*] -1> [*, , ]
Then moving times = 6, current index will be 0 again:
[*, , ] -6> [ ,*, ] -5> [ , ,*] -4> [*, , ] -3> [ ,*, ] -2> [ , ,*] -1> [*, , ]
In that case we can cut the moving times from 6 to 3. That is “cut moving times” here.
TODO: We can write more optimized code which resets all elements with Array.new if given moving times is greater than `@size`.
# File lib/expeditor/ring_buffer.rb, line 59 def cut_moving_time_if_possible(times) if times >= @size * 2 (times % @size) + @size else times end end
# File lib/expeditor/ring_buffer.rb, line 67 def next_element if @current_index == @size - 1 @current_index = 0 else @current_index += 1 end @elements[@current_index] = @initialize_proc.call end