右键!这是我对循环缓冲区的尝试(用于图形程序,使用canvas元素)。还没有完成测试。
问题是 - 我的逻辑中是否有人能看到任何缺陷?还是瓶颈?
/**
* A circular buffer class.
* @To add value -> bufferObject.addValue(xValue, yValue);
* @To get the First-in value use -> bufferObject.getValue(0);
* @To get the Last-in value use -> bufferObject.getValue(bufferObject.length);
**/
var circularBuffer = function (bufferSize) {
this.bufferSize = bufferSize;
this.buffer = new Array(this.bufferSize); // After testing on jPerf -> 2 x 1D array seems fastest solution.
this.end = 0;
this.start = 0;
// Adds values to array in circular.
this.addValue = function(xValue, yValue) {
this.buffer[this.end] = {x : xValue, y: yValue};
if (this.end != this.bufferSize) this.end++;
else this.end = 0;
if(this.end == this.start) this.start ++;
};
// Returns a value from the buffer
this.getValue = function(index) {
var i = index+this.start;
if(i >= this.bufferSize) i -= this.bufferSize; //Check here.
return this.buffer[i]
};
// Returns the length of the buffer
this.getLength = function() {
if(this.start > this.end || this.start == this.bufferSize) {
return this.xBuffer.length;
} else {
return this.end - this.start;
}
};
// Returns true if the buffer has been initialized.
this.isInitialized = function() {
if(this.end != this.start) return true;
else return false;
};
}
请随意重复使用此代码。
更新了两次(并经过测试!)。
答案 0 :(得分:1)
更新:找到另一个实施Circular buffer in JavaScript
将类变量设为私有,更正了旧的xBuffer引用。今晚会做更多的编辑。
/**
* A circular buffer class.
* @To add value -> bufferObject.addValue(xValue, yValue);
* @To get the First-in value use -> bufferObject.getValue(0);
* @To get the Last-in value use -> bufferObject.getValue(bufferObject.length);
**/
var circularBuffer = function (buffer_size) {
var bufferSize = buffer_size;
var buffer = new Array(bufferSize); // After testing on jPerf -> 2 x 1D array seems fastest solution.
var end = 0;
var start = 0;
// Adds values to array in circular.
this.addValue = function(xValue, yValue) {
buffer[end] = {x : xValue, y: yValue};
if (end != bufferSize) end++;
else end = 0;
if(end == start) start++;
};
// Returns a value from the buffer
this.getValue = function(index) {
var i = index+start;
if(i >= bufferSize) i -= bufferSize; //Check here.
return buffer[i];
};
// Returns the length of the buffer
this.getLength = function() {
if(start > end || start == bufferSize) {
return buffer.length;
} else {
return end - start;
}
};
// Returns true if the buffer has been initialized.
this.isInitialized = function() {
return (end != start) ? true : false;
};
}
答案 1 :(得分:0)
我在上面实现了Vogomatix的代码,并且遇到了一些错误。代码写下缓冲区的末尾,自动扩展缓冲区大小,并且addValue函数绑定到特定类型。我调整了代码以适应任何对象类型,添加了一些私有子例程来简化,并添加了一个函数来将内容转储到字符串,并带有可选的分隔符。还使用了命名空间。
缺少的是removeValue(),但只是检查计数大于零,然后调用_pop()。
这样做是因为我需要一个滚动的,滚动的文本缓冲区用于入站消息,它不会无限增长。我使用带有textarea的对象,所以我得到的行为就像一个控制台窗口,一个滚动的文本框,不会无限期地咀嚼内存。
我已经考虑到了权宜之计,因为我编写得很快,在这里发布,希望OverFlow-ers使用并退火代码。
///////////////////////////////////////////////////////////////////////////////
// STYLE DECLARATION
// Use double quotes in JavaScript
///////////////////////////////////////////////////////////////////////////////
// Global Namespace for this application
//
var nz = nz || {};
nz.cbuffer = new Object();
///////////////////////////////////////////////////////////////////////////////
// CIRCULAR BUFFER
//
// CREDIT:
// Based on...
// Vogomatix http://stackoverflow.com/questions/20119513/attempt-at-circular-buffer-javascript
// But re-written after finding some undocumented features...
/**
* A circular buffer class, storing any type of Javascript object.
* To add value -> bufferObject.addValue(obj);
* To get the First-in value use -> bufferObject.getValue(0);
* To get the Last-in value use -> bufferObject.getValue(bufferObject.length);
* To dump to string use -> bufferObject.streamToString(sOptionalDelimiter); // Defaults to "\r\n"
**/
nz.cbuffer.circularBuffer = function (buffer_size) {
var bufferSize = buffer_size > 0 ? buffer_size : 1; // At worst, make an array of size 1
var buffer = new Array(bufferSize);
var end = 0; // Index of last element.
var start = 0; // Index of first element.
var count = 0; // Count of elements
// 'Private' function to push object onto buffer.
this._push = function (obj) {
buffer[end] = obj; // Write
end++; // Advance
if (end == bufferSize) {
end = 0; // Wrap if illegal
}
count++;
}
// 'Private' function to pop object from buffer.
this._pop = function () {
var obj = buffer[start];
start++;
if (start == bufferSize) {
start = 0; // Wrap
}
count--;
return obj;
}
// Adds values to buffer.
this.addValue = function (obj) {
if (count < bufferSize) {
// Just push
this._push(obj);
}
else {
// Pop, then push
this._pop();
this._push(obj);
}
}
// Returns a value from the buffer. Index is relative to current notional start.
this.getValue = function (index) {
if (index >= count || index < 0) return; // Catch attempt to access illegal index
var i = index + start;
if (i >= bufferSize) {
i -= bufferSize;
}
return buffer[i];
}
// Returns the length of the buffer.
this.getLength = function () {
return count;
}
// Returns all items as strings, separated by optional delimiter.
this.streamToString = function (delim) {
delim = (typeof delim === "undefined") ? "\r\n" : delim; // Default syntax; Default to CRLF
var strReturn = "";
var once = 0;
var index = 0;
var read = index + start;
for (; index < count; ++index) {
if (once == 1) strReturn += delim.toString();
strReturn += buffer[read].toString();
read++;
if (read >= bufferSize) read = 0;
once = 1;
}
return strReturn;
}
}