Circular buffer 尝试使用循环缓冲区-Javascript

Circular buffer 尝试使用循环缓冲区-Javascript,circular-buffer,Circular Buffer,对!!下面是我对循环缓冲区的尝试(用于图形程序中,使用canvas元素)。还没有抽出时间来测试它 问题是——有人能看出我的逻辑有什么缺陷吗?还是瓶颈 /** * A circular buffer class. * @To add value -> bufferObject.addValue(xValue, yValue); * @To get the First-in value use -> bufferObject.getValue(0); * @To get

对!!下面是我对循环缓冲区的尝试(用于图形程序中,使用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;
    };
}
请随意重用此代码


更新了两次(并经过测试!)。

更新:找到了另一个实现

使类变量私有,更正旧xBuffer引用。今晚将做更多的编辑

/**
*循环缓冲区类。
*@To add value->bufferObject.addValue(xValue,yValue);
*@使用->bufferObject.getValue(0)获取第一个输入值;
*@使用->bufferObject.getValue(bufferObject.length)获取最后一个输入值;
**/
var circularBuffer=函数(缓冲区大小){
var bufferSize=缓冲区大小;
var buffer=new Array(bufferSize);//在jPerf->2 x 1D上测试后,数组似乎是最快的解决方案。
var-end=0;
var start=0;
//向循环数组中添加值。
this.addValue=函数(xValue,yValue){
缓冲区[end]={x:xValue,y:yValue};
如果(end!=bufferSize)end++;
else-end=0;
如果(end==start)start++;
};
//从缓冲区返回一个值
this.getValue=函数(索引){
var i=指数+开始;
如果(i>=bufferSize)i-=bufferSize;//检查这里。
返回缓冲区[i];
};
//返回缓冲区的长度
this.getLength=函数(){
如果(开始>结束| |开始==缓冲区大小){
返回缓冲区长度;
}否则{
返回结束-开始;
}
};
//如果缓冲区已初始化,则返回true。
this.isInitialized=函数(){
返回(结束!=开始)?真:假;
};
}

我实现了上面的Vogomatix代码,并得到了一些bug。代码注销缓冲区的结尾,自动扩展缓冲区大小,addValue函数绑定到特定类型。我已经调整了代码以处理任何对象类型,添加了一些私有子例程以简化,并添加了一个函数以将内容转储到字符串中,并使用可选的分隔符。还使用了名称空间

缺少的是removeValue(),但它只是检查计数是否大于零,然后调用_pop()

之所以这样做,是因为我需要一个滚动、滚动的文本缓冲区来存储入站消息,而这个缓冲区不会无限增长。我使用带有文本区域的对象,所以我得到的行为就像控制台窗口,一个滚动的文本框,不会无限期地消耗内存

这已经在考虑权宜之计的情况下进行了测试,因为我正在快速编写代码,发布在这里,希望其他溢出者使用并退火代码

///////////////////////////////////////////////////////////////////////////////
// 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;
    }
}
///////////////////////////////////////////////////////////////////////////////
//样式声明
//在JavaScript中使用双引号
///////////////////////////////////////////////////////////////////////////////
//此应用程序的全局命名空间
//
var nz=nz |{};
nz.cbuffer=新对象();
///////////////////////////////////////////////////////////////////////////////
//循环缓冲器
//
//学分:
//基于。。。
//Vogomatixhttp://stackoverflow.com/questions/20119513/attempt-at-circular-buffer-javascript
//但在找到一些未记录的功能后重新编写。。。
/**
*循环缓冲区类,存储任何类型的Javascript对象。
*添加值->bufferObject.addValue(obj);
*要获取第一个in值,请使用->bufferObject.getValue(0);
*要获取最后一个输入值,请使用->bufferObject.getValue(bufferObject.length);
*要转储到字符串,请使用->bufferObject.streamToString(SOPationalDelimiter);//默认为“\r\n”
**/
nz.cbuffer.circularBuffer=函数(缓冲区大小){
var bufferSize=buffer\u size>0?buffer\u size:1;//最坏情况下,创建一个大小为1的数组
var buffer=新数组(bufferSize);
var end=0;//最后一个元素的索引。
var start=0;//第一个元素的索引。
var count=0;//元素的计数
//“Private”函数将对象推送到缓冲区。
此按钮=功能(obj){
缓冲区[end]=obj;//写入
结束+++;//前进
if(end==bufferSize){
end=0;//如果非法则换行
}
计数++;
}
//“Private”函数从缓冲区弹出对象。
这是一个函数(){
var obj=缓冲区[启动];
启动++;
如果(开始==缓冲区大小){
start=0;//换行
}
计数--;
返回obj;
}
//将值添加到缓冲区。
this.addValue=函数(obj){
如果(计数<缓冲区大小){
//推一下
这个。_推(obj);
}
否则{
//弹出,然后推
这个;
这个。_推(obj);
}
}
//从缓冲区返回一个值。索引是相对于当前名义开始的。
this.getValue=函数(索引){
if(index>=count | | index<0)return;//Catch试图访问非法索引
var i=指数+开始;
如果(i>=缓冲区大小){
i-=缓冲区大小;
}
返回缓冲区[i];
}
//返回缓冲区的长度。
this.getLength=函数(){
返回计数;
}
//以字符串形式返回所有项,并用可选分隔符分隔。
this.streamToString=函数(delim){
delim=(typeof delim==“undefined”)?“\r\n”:delim;//默认语法;默认为CRLF
var strReturn=“”;
var一次=0;
var指数=0;
变量读取=索引+开始;
对于(;索引<计数;++索引){
如果(once==1)strReturn+=delim.toString();
strReturn+=缓冲区[read].toString();
读++;
如果(读取>=bufferSize)读取=0;
一次=1;
}
返回strReturn;
}
}

是的,在此.getValue中计算缓冲区索引的次数太多。x和y对一起运行,所以