三维循环缓冲区

时间:2016-03-20 10:10:28

标签: c# .net

我正在寻找C#.NET中三维循环缓冲区的实现,它允许我提取缓冲区的切片。

我尝试了多维数组,但它不允许我获取缓冲区的特定切片。

我还尝试使用锯齿状数组实现一个版本,但我发现在理解如何初始化矩阵以及切片提取方面存在一些问题。

感谢您的帮助。

[编辑1] 缓冲区将用于存储来自reltime传感器的数据,它将以宽度高度固定,深度(时间为圆形部分)将由用户定义。

我需要的切片是固定大小的矩阵(宽度和高度与给定时间的数据)。

[编辑2] 我可以实现的唯一实现。随着锯齿状阵列我仍然坚持声明(我觉得它很混乱)

public class CircularBufferMatrix<T>
{
    private readonly T[,,] _buffer;

    public CircularBufferMatrix(int width, int height, int depth)
    {
        Width = width;
        Height = height;
        Depth = depth;
        _buffer = new T[width, height, depth];
    }

    public T this[int x, int y, int z]
    {
        set { _buffer[x, y, z%Depth] = value; }
        get { return _buffer[x, y, z%Depth]; }
    }

    #region Getters

    public int Width { get; }

    public int Height { get; }

    public int Depth { get; }

    #endregion
}

2 个答案:

答案 0 :(得分:1)

我会将这些分为两类。你想要一个类似CircularBuffer类的东西,它处理读写。另一个可能是您要存储的2D数组的实现。拆分这些的原因是因为你想分别读/写帧。

例如:

循环缓冲区实现:

public class CircularBuffer<T>
{
    private T[] _buffer;

    private int IncRollover(int value)
    {
        value++;
        if (value >= _buffer.Length)
            value = 0;

        return value;
    }

    public CircularBuffer(int count)
    {
        _buffer = new T[count];
    }

    public bool Write(T element)
    {
        // if the writeindex (after increasing) equals the readindex, the buffer is full
        var newWriteIndex = IncRollover(WriteIndex);
        if (newWriteIndex == ReadIndex)
            return false;

        _buffer[WriteIndex] = element;

        WriteIndex = newWriteIndex;
        return true;
    }

    public bool TryRead(out T element)
    {
        if (ReadIndex == WriteIndex)
        {
            element = default(T);
            return false;
        }

        element = _buffer[ReadIndex];
        ReadIndex = IncRollover(ReadIndex);

        return true;
    }

    public IEnumerable<T> ReadAll()
    {
        T element;
        while (TryRead(out element))
            yield return element;
    }


    public int ReadIndex { get; private set; }
    public int WriteIndex { get; private set; }
}

这将负责读取和写入有效的“帧”/切片。如果您想阅读索引,可以扩展此课程。

注意:如果缓冲区已满,写入将返回false

这可能是存储在循环缓冲区中的2d缓冲区的实现:

public class MyWhateverBuffer<T>
{
    private CircularBuffer<T[,]> _buffer;

    public int Width { get; private set; }
    public int Height { get; private set; }
    public int Depth { get; private set; }

    public MyWhateverBuffer(int width, int height, int depth)
    {
        Width = width;
        Height = height;
        Depth = depth;
        _buffer = new CircularBuffer<T[,]>(depth);
    }

    public T[,] New()
    {
        return new T[Width, Height];
    }

    public bool Add(T[,] buffer)
    {
        return _buffer.Write(buffer);
    }

    public bool TryRead(out T[,] buffer)
    {
        return _buffer.TryRead(out buffer);
    }

    public IEnumerable<T[,]> ReadAll()
    {
        return _buffer.ReadAll();
    }
}

这个类可以像:

一样使用
MyWhateverBuffer<double> myBuffer = new MyWhateverBuffer<double>(100, 100, 100);

var oneSlice = myBuffer.New();

oneSlice[10, 10] = 3.5;
oneSlice[50, 10] = 23.5;
oneSlice[10, 20] = 43.5;

myBuffer.Add(oneSlice);

var anotherSlice = myBuffer.New();

anotherSlice[10, 10] = 13.5;
anotherSlice[50, 10] = 23.5;
anotherSlice[10, 20] = 43.5;

var result = myBuffer.Add(anotherSlice);

if(!result)
{
    // the buffer was full..
}

// Read the results from the buffer.
foreach(var slice in myBuffer.ReadAll())
{
    Trace.WriteLine(slice[10, 10]);
}

您应该始终检查是否可以添加缓冲区。你不想丢失信息。

旁注:

使用循环缓冲区获得的利润最多的是声明元素。像大数组一样,每次都会重复使用。

答案 1 :(得分:0)

如果我正确理解您的要求,您需要一个循环缓冲区,该缓冲区由二维数据数组组成,而其他项中的数据永远不会重复。 C#没有cicular缓冲区类型,但您可以自己创建一个: -

public class CircularBuffer <T> // make it generic
{
  public class Iterator
  {
    public void MoveForward ();
    public void MoveBackward ();
    public T Item { get { } };

    CicrcularBuffer <T> m_container;
    LinkedListNode <T> m_current_item;
  }

  public void Add (T item);
  public Iterator GetIterator ();

  LinkedList<T> m_data;
}

然后创建一个包含数据的类: -

public class SensorData
{
  // contains the two dimension data
}

并使用它: -

var buffer = new CircularBuffer <SensorData> ();
var iterator = buffer.GetIterator ();
var item = iterator.Item;
iterator.MoveForward ();

显然,有很多东西需要填写,但它应该让你开始。

相关问题