2013-04-30 40 views
5

Chỉ cần làm phiền ở đây, với bộ đệm tròn. Đây có phải là một sự thực hiện hợp lý hoặc có một cách nhanh hơn/đáng tin cậy hơn để da mèo này?bộ sưu tập scala bộ đệm tròn

class CircularBuffer[T](size: Int)(implicit mf: Manifest[T]) { 

    private val arr = new scala.collection.mutable.ArrayBuffer[T]() 

    private var cursor = 0 

    val monitor = new ReentrantReadWriteLock() 

    def push(value: T) { 
     monitor.writeLock().lock() 
     try { 
     arr(cursor) = value 
     cursor += 1 
     cursor %= size 
     } finally { 
     monitor.writeLock().unlock() 
     } 
    } 

    def getAll: Array[T] = { 
     monitor.readLock().lock() 
     try { 
     val copy = new Array[T](size) 
     arr.copyToArray(copy) 
     copy 
     } finally { 
     monitor.readLock().unlock() 
     } 
    } 
    } 
+1

Kể từ bộ đệm của bạn là kích thước cố định, sử dụng một 'Array' như đại diện nội bộ. – gzm0

+1

Bạn cũng nên xem xét trình phá rối, về cơ bản nó là một bộ đệm tròn https://github.com/LMAX-Exchange/disruptor – Noah

+0

gzm0, tôi không muốn phân bổ toàn bộ không gian, lên phía trước. Đó là lý do tại sao tôi đã có một giới hạn trên về kích thước nhưng sử dụng một ArrayBuffer nội bộ. đó có phải là ý tưởng tồi tệ không? – irishjava

Trả lời

3

Creation

Tôi sẽ sử dụng khai báo kiểu và một chức năng cộng thay vì "cán của riêng bạn":

import scala.collection.immutable 

type CircularBuffer[T] = immutable.Vector[T] 

def emptyCircularBuffer[T] : CircularBuffer[T] = immutable.Vector.empty[T] 

def addToCircularBuffer[T](maxSize : Int)(buffer : CircularBuffer[T], item : T) : CircularBuffer[T] = 
    (buffer :+ item) takeRight maxSize 

Điều này có nghĩa rằng bạn "CircularBuffer" thực sự là một Vector và bạn hiện có tất cả các phương thức Vector tương ứng (bộ lọc, bản đồ, sơ đồ phẳng, v.v ...) miễn phí:

var intCircularBuffer = emptyCircularBuffer[Int] 

//Vector(41) 
intCircularBuffer = addToCircularBuffer(2)(intCircularBuffer, 41) 

//Vector(41, 42) 
intCircularBuffer = addToCircularBuffer(2)(intCircularBuffer, 42) 

//Vector(42, 43) 
intCircularBuffer = addToCircularBuffer(2)(intCircularBuffer, 43) 

//Vector(42) 
val evens : CircularBuffer[Int] = intCircularBuffer filter (_ % 2 == 0) 

Indexing

Bạn tương tự có thể thêm một chức năng cho chỉ mục tròn:

def circularIndex[T](buffer : CircularBuffer[T])(index : Int) : T = 
    buffer(index % buffer.size)