All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.twitter.util.RingBuffer.scala Maven / Gradle / Ivy

The newest version!
package com.twitter.util

class RingBuffer[A: ClassManifest](val maxSize: Int) extends Seq[A] {
  private val array = new Array[A](maxSize)
  private var read = 0
  private var write = 0
  private var count_ = 0

  def length = count_
  override def size = count_

  def clear() {
    read = 0
    write = 0
    count_ = 0
  }

  /**
   * Gets the element from the specified index in constant time.
   */
  def apply(i: Int): A = {
    if (i >= count_) throw new IndexOutOfBoundsException(i.toString)
    else array((read + i) % maxSize)
  }

  /**
   * Overwrites an element with a new value
   */
  def update(i: Int, elem: A) {
    if (i >= count_) throw new IndexOutOfBoundsException(i.toString)
    else array((read + i) % maxSize) = elem
  }

  /**
   * Adds an element, possibly overwriting the oldest elements in the buffer
   * if the buffer is at capacity.
   */
  def +=(elem: A) {
    array(write) = elem
    write = (write + 1) % maxSize
    if (count_ == maxSize) read = (read + 1) % maxSize
    else count_ += 1
  }

  /**
   * Adds multiple elements, possibly overwriting the oldest elements in
   * the buffer.  If the given iterable contains more elements that this
   * buffer can hold, then only the last maxSize elements will end up in
   * the buffer.
   */
  def ++=(iter: Iterable[A]) {
    for (elem <- iter) this += elem
  }

  /**
   * Removes the next element from the buffer
   */
  def next: A = {
    if (read == write) throw new NoSuchElementException
    else {
      val res = array(read)
      read = (read + 1) % maxSize
      count_ -= 1
      res
    }
  }

  override def iterator = new Iterator[A] {
    var idx = 0
    def hasNext = idx != count_
    def next = {
      val res = apply(idx)
      idx += 1
      res
    }
  }

  override def drop(n: Int): RingBuffer[A] = {
    if (n >= maxSize) clear()
    else read = (read + n) % maxSize
    this
  }

  def removeWhere(fn: A=>Boolean): Int = {
    var rmCount_ = 0
    var j = 0
    for (i <- 0 until count_) {
      val elem = apply(i)
      if (fn(elem)) rmCount_ += 1
      else {
        if (j < i) update(j, elem)
        j += 1
      }
    }
    count_ -= rmCount_
    write = (read + count_) % maxSize
    rmCount_
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy