Changeset - 5e8115ecea3b
[Not reviewed]
longmem
0 3 0
Hasan Yavuz ÖZDERYA - 6 years ago 2020-01-29 15:27:34
hy@ozderya.net
make chunked buffer based on FrameBuffer
3 files changed with 35 insertions and 24 deletions:
0 comments (0 inline, 0 general)
src/chunkedbuffer.cpp
Show inline comments
 
/*
 
  Copyright © 2017 Hasan Yavuz Özderya
 
  Copyright © 2020 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
  serialplot is free software: you can redistribute it and/or modify
 
  it under the terms of the GNU General Public License as published by
 
  the Free Software Foundation, either version 3 of the License, or
 
@@ -33,32 +33,32 @@ ChunkedBuffer::~ChunkedBuffer()
 
    for (auto chunk : chunks)
 
    {
 
        delete chunk;
 
    }
 
}
 

	
 
void ChunkedBuffer::addSamples(double* samples, size_t size)
 
void ChunkedBuffer::addSamples(double* samples, unsigned n)
 
{
 
    size_t i = 0;
 

	
 
    while (i < size)
 
    while (i < n)
 
    {
 
        // select chunk to add data
 
        auto chunk = chunks.last();
 
        if (chunk->isFull())
 
        {
 
            chunk = addNewChunk(); // create a new chunk
 
        }
 

	
 
        // add data to chunk
 
        size_t c = std::min(chunk->left(), (size - i));
 
        size_t c = std::min(chunk->left(), (n - i));
 
        chunk->addSamples(&samples[i], c);
 
        i += c;
 
    }
 

	
 
    _size += size;
 
    _size += n;
 
}
 

	
 
void ChunkedBuffer::clear()
 
{
 
    // delete all chunks
 
    for (auto chunk : chunks)
 
@@ -78,18 +78,18 @@ DataChunk* ChunkedBuffer::addNewChunk()
 
{
 
    auto chunk = new DataChunk(_size, CHUNK_SIZE);
 
    chunks.append(chunk);
 
    return chunk;
 
}
 

	
 
size_t ChunkedBuffer::size() const
 
unsigned ChunkedBuffer::size() const
 
{
 
    return _size;
 
}
 

	
 
QRectF ChunkedBuffer::boundingRect() const
 
Range ChunkedBuffer::limits() const
 
{
 
    // TODO: it should be possible to cache boundingRect and only
 
    // update on 'addSamples' and when dropping chunks
 

	
 
    // find ymin and ymax
 
    double ymin = chunks.first()->min();
 
@@ -97,15 +97,20 @@ QRectF ChunkedBuffer::boundingRect() con
 
    for (auto c : chunks)
 
    {
 
        ymin = std::min(ymin, c->min());
 
        ymax = std::max(ymax, c->max());
 
    }
 

	
 
    return QRectF(0, ymax, _size, (ymax-ymin));
 
    return {ymin, ymax};
 
}
 

	
 
double ChunkedBuffer::sample(size_t i) const
 
double ChunkedBuffer::sample(unsigned i) const
 
{
 
    int chunk_index = i / CHUNK_SIZE;
 
    int chunk_offset = i % CHUNK_SIZE;
 
    return chunks[chunk_index]->sample(chunk_offset);
 
}
 

	
 
void ChunkedBuffer::resize(unsigned n)
 
{
 
    // TODO what to do for ChunkedBuffer::resize
 
}
src/chunkedbuffer.h
Show inline comments
 
/*
 
  Copyright © 2017 Hasan Yavuz Özderya
 
  Copyright © 2020 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
  serialplot is free software: you can redistribute it and/or modify
 
  it under the terms of the GNU General Public License as published by
 
  the Free Software Foundation, either version 3 of the License, or
 
@@ -22,28 +22,29 @@
 

	
 
#include <QPointF>
 
#include <QRectF>
 
#include <QVector>
 

	
 
#include "datachunk.h"
 
#include "framebuffer.h"
 

	
 
#define CHUNK_SIZE (1024)
 

	
 
class ChunkedBuffer
 
class ChunkedBuffer : public WFrameBuffer
 
{
 
public:
 
    ChunkedBuffer();
 
    ~ChunkedBuffer();
 

	
 
    void addSamples(double* samples, size_t size);
 
    void clear();
 

	
 
    // QwtSeriesData related implementations
 
    size_t size() const;
 
    QRectF boundingRect() const;
 
    double sample(size_t i) const;
 
    // FrameBuffer related implementations
 
    virtual unsigned size() const;
 
    virtual double sample(unsigned i) const;
 
    virtual Range limits() const;
 
    virtual void resize(unsigned n);
 
    virtual void addSamples(double* samples, unsigned n);
 
    virtual void clear();
 

	
 
private:
 
    size_t _size; // size of `data`
 
    size_t numChunks;
 

	
 
    QList<DataChunk*> chunks;
tests/test.cpp
Show inline comments
 
/*
 
  Copyright © 2018 Hasan Yavuz Özderya
 
  Copyright © 2020 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
  serialplot is free software: you can redistribute it and/or modify
 
  it under the terms of the GNU General Public License as published by
 
  the Free Software Foundation, either version 3 of the License, or
 
@@ -451,43 +451,48 @@ TEST_CASE("filling data chunk", "[memory
 

	
 
TEST_CASE("ChunkedBuffer created empty", "[memory]")
 
{
 
    ChunkedBuffer b;
 

	
 
    REQUIRE(b.size() == 0);
 
    REQUIRE(b.boundingRect() == QRectF(0,0,0,0));
 
    REQUIRE(b.limits().start == 0);
 
    REQUIRE(b.limits().end == 0);
 
}
 

	
 
TEST_CASE("ChunkedBuffer adding data and clearing", "[memory]")
 
{
 
    ChunkedBuffer b;
 

	
 
    // add some small data
 
    const int N = 10;
 
    double samples[N] = {1,2,3,4,5,6,7,8,9,10};
 
    b.addSamples(samples, N);
 

	
 
    REQUIRE(b.size() == N);
 
    REQUIRE(b.boundingRect() == QRectF(0,10,N,9));
 
    REQUIRE(b.limits().start == 1);
 
    REQUIRE(b.limits().end == 10);
 

	
 
    // add data to fill the chunk
 
    double samples2[CHUNK_SIZE-N] = {0};
 
    b.addSamples(samples2, CHUNK_SIZE-N);
 
    REQUIRE(b.size() == CHUNK_SIZE);
 
    REQUIRE(b.boundingRect() == QRectF(0,10,CHUNK_SIZE,10));
 
    REQUIRE(b.limits().start == 0);
 
    REQUIRE(b.limits().end == 10);
 

	
 
    // add data for second chunk
 
    b.addSamples(samples, N);
 
    REQUIRE(b.size() == CHUNK_SIZE+N);
 
    REQUIRE(b.boundingRect() == QRectF(0,10,CHUNK_SIZE+N,10));
 
    REQUIRE(b.limits().start == 0);
 
    REQUIRE(b.limits().end == 10);
 

	
 
    // add more data to make it 4 chunks
 
    double samples3[CHUNK_SIZE*3-N] = {0};
 
    b.addSamples(samples3, CHUNK_SIZE*3-N);
 
    REQUIRE(b.size() == CHUNK_SIZE*4);
 
    REQUIRE(b.boundingRect() == QRectF(0,10,CHUNK_SIZE*4,10));
 
    REQUIRE(b.limits().start == 0);
 
    REQUIRE(b.limits().end == 10);
 

	
 
    // clear
 
    b.clear();
 
    REQUIRE(b.size() == 0);
 
}
 

	
0 comments (0 inline, 0 general)