【发布时间】:2016-06-30 22:13:10
【问题描述】:
我将一个有效的循环缓冲区 buf 保留为一个数组和两个总读写计数 bufRead 和 bufWrite 以便 bufRead % buf.length 和 bufWrite % buf.length 是当前操作的缓冲区的正确索引。
现在我可能需要在某个时候“增长”数组,因为缓冲区大小会扩大。所以我想用一个新的更大的数组替换buf,但保留缓冲区的所有先前内容同时保留上述模数属性。因此,如果在旧缓冲区中的bufRead % buf.length 我们找到元素X,那么我希望在buf 之后的同一索引bufRead % buf.length 处再次找到这个元素X已更新。
例子:
trait Algorithm {
var buf: Array[Double]
var bufRead : Long // this won't be needed in `resize`
var bufWrite: Long // this won't be needed in `resize`
def resize(newLength: Int): Unit = {
val newBuf = new Array[Double](newLength)
???
buf = newBuf
}
}
测试程序:
def test(in: Algorithm): Unit = {
import in._
import math.{min, random}
val avail = buf.length // (bufWrite - bufRead).toInt
val data0 = Array.fill(avail)(random)
val off0 = (bufRead % buf.length).toInt
val chunk0 = min(avail, buf.length - off0)
val off1 = (off0 + chunk0) % buf.length
val chunk1 = avail - chunk0
System.arraycopy(data0, 0 , buf, off0, chunk0)
System.arraycopy(data0, chunk0, buf, off1, chunk1)
resize(avail * 2) // arbitrary growth
val data1 = new Array[Double](avail)
val off2 = (bufRead % buf.length).toInt
val chunk2 = min(avail, buf.length - off2)
val off3 = (off2 + chunk2) % buf.length
val chunk3 = avail - chunk2
System.arraycopy(buf, off2, data1, 0 , chunk2)
System.arraycopy(buf, off3, data1, chunk2, chunk3)
assert(data0 sameElements data1)
}
【问题讨论】:
-
你想要
a % b = a % c,其中b < c。对我来说似乎不可能。您是否考虑过创建更多相同大小的缓冲区而不是扩大当前缓冲区?你当然需要做一些整理工作来弄清楚哪些缓冲区被推入了,但至少你可以保留你的模数属性。另一种选择是增加可以保存在单个缓冲区位置中的项目数量,但再次与您想要的不同...... -
@wookie919 不!索引可能会因更新而改变,但在更新前后计算的索引处的内容必须保持不变。因此,要保存的内容位于
(bufRead until (bufRead + oldLength)) % buf.length
标签: algorithm scala circular-buffer