class Datadog::Buffer

Buffer that stores objects. The buffer has a maximum size and when the buffer is full, a random object is discarded.

Public Class Methods

new(max_size) click to toggle source
# File lib/ddtrace/buffer.rb, line 10
def initialize(max_size)
  @max_size = max_size
  @items = []
  @closed = false
end

Public Instance Methods

close() click to toggle source

Closes this buffer, preventing further pushing. Draining is still allowed.

# File lib/ddtrace/buffer.rb, line 57
def close
  @closed = true
end
closed?() click to toggle source
# File lib/ddtrace/buffer.rb, line 61
def closed?
  @closed
end
concat(items) click to toggle source

A bulk push alternative to #push. Use this method if pushing more than one item for efficiency.

# File lib/ddtrace/buffer.rb, line 27
def concat(items)
  return if closed?

  # Segment items into underflow and overflow
  underflow, overflow = overflow_segments(items)

  # Concatenate items do not exceed capacity.
  add_all!(underflow) unless underflow.nil?

  # Iteratively replace items, to ensure pseudo-random replacement.
  overflow.each { |item| replace!(item) } unless overflow.nil?
end
empty?() click to toggle source

Return if the buffer is empty.

# File lib/ddtrace/buffer.rb, line 51
def empty?
  @items.empty?
end
length() click to toggle source

Return the current number of stored traces.

# File lib/ddtrace/buffer.rb, line 46
def length
  @items.length
end
pop() click to toggle source

Stored items are returned and the local buffer is reset.

# File lib/ddtrace/buffer.rb, line 41
def pop
  drain!
end
push(item) click to toggle source

Add a new “item“ in the local queue. This method doesn't block the execution even if the buffer is full. In that case, a random item is discarded.

# File lib/ddtrace/buffer.rb, line 18
def push(item)
  return if closed?

  full? ? replace!(item) : add!(item)
  item
end

Protected Instance Methods

add!(item) click to toggle source
# File lib/ddtrace/buffer.rb, line 104
def add!(item)
  @items << item
end
add_all!(items) click to toggle source
# File lib/ddtrace/buffer.rb, line 100
def add_all!(items)
  @items.concat(items)
end
drain!() click to toggle source
# File lib/ddtrace/buffer.rb, line 120
def drain!
  items = @items
  @items = []
  items
end
full?() click to toggle source
# File lib/ddtrace/buffer.rb, line 96
def full?
  @max_size > 0 && @items.length >= @max_size
end
overflow_segments(items) click to toggle source

Segment items into two distinct segments: underflow and overflow. Underflow are items that will fit into buffer. Overflow are items that will exceed capacity, after underflow is added. Returns each array, and nil if there is no underflow/overflow.

# File lib/ddtrace/buffer.rb, line 71
def overflow_segments(items)
  underflow = nil
  overflow = nil

  overflow_size = @max_size > 0 ? (@items.length + items.length) - @max_size : 0

  if overflow_size > 0
    # Items will overflow
    if overflow_size < items.length
      # Partial overflow
      underflow_end_index = items.length - overflow_size - 1
      underflow = items[0..underflow_end_index]
      overflow = items[(underflow_end_index + 1)..-1]
    else
      # Total overflow
      overflow = items
    end
  else
    # Items do not exceed capacity.
    underflow = items
  end

  [underflow, overflow]
end
replace!(item) click to toggle source
# File lib/ddtrace/buffer.rb, line 108
def replace!(item)
  # Choose random item to be replaced
  replace_index = rand(@items.length)

  # Replace random item
  discarded_item = @items[replace_index]
  @items[replace_index] = item

  # Return discarded item
  discarded_item
end