Changeset - ec2bd041e1de
[Not reviewed]
longmem
0 2 0
Hasan Yavuz Ă–ZDERYA - 8 years ago 2017-08-12 12:58:41
hy@ozderya.net
added clear method
2 files changed with 19 insertions and 3 deletions:
0 comments (0 inline, 0 general)
src/chunkedbuffer.cpp
Show inline comments
 
@@ -13,83 +13,99 @@
 
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
  GNU General Public License for more details.
 

	
 
  You should have received a copy of the GNU General Public License
 
  along with serialplot.  If not, see <http://www.gnu.org/licenses/>.
 
*/
 

	
 
#include "chunkedbuffer.h"
 

	
 
ChunkedBuffer::ChunkedBuffer()
 
{
 
    numChunks = 0;
 
    _size = 0;
 

	
 
    // create first chunk
 
    addNewChunk();
 
}
 

	
 
ChunkedBuffer::~ChunkedBuffer()
 
{
 
    for (auto chunk : chunks)
 
    {
 
        delete chunk;
 
    }
 
}
 

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

	
 
    while (i < size)
 
    {
 
        // 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));
 
        chunk->addSamples(&samples[i], c);
 
        i += c;
 
    }
 

	
 
    _size += size;
 
}
 

	
 
void ChunkedBuffer::clear()
 
{
 
    // delete all chunks
 
    for (auto chunk : chunks)
 
    {
 
        delete chunk;
 
    }
 
    chunks.clear();
 

	
 
    numChunks = 0;
 
    _size = 0;
 

	
 
    // create first chunk
 
    addNewChunk();
 
}
 

	
 
DataChunk* ChunkedBuffer::addNewChunk()
 
{
 
    auto chunk = new DataChunk(_size, CHUNK_SIZE);
 
    chunks.append(chunk);
 
    return chunk;
 
}
 

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

	
 
QRectF ChunkedBuffer::boundingRect() 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();
 
    double ymax = chunks.first()->max();
 
    for (auto c : chunks)
 
    {
 
        ymin = std::min(ymin, c->min());
 
        ymax = std::max(ymax, c->max());
 
    }
 

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

	
 
double ChunkedBuffer::sample(size_t i) const
 
{
 
    int chunk_index = i / CHUNK_SIZE;
 
    int chunk_offset = i % CHUNK_SIZE;
 
    return chunks[chunk_index]->sample(chunk_offset);
 
}
tests/test.cpp
Show inline comments
 
@@ -71,79 +71,79 @@ TEST_CASE("filling data chunk", "[memory
 
    REQUIRE(c.capacity() == 1000);
 
    REQUIRE(c.start() == 0);
 
    REQUIRE(c.end() == 1000);
 
    REQUIRE(c.left() == 0);
 

	
 
    REQUIRE(c.min() == 1);
 
    REQUIRE(c.max() == 1000);
 
    REQUIRE(c.avg() == Approx(500.5));
 
    REQUIRE(c.meanSquare() == Approx(333833.5));
 
}
 

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

	
 
    REQUIRE(b.size() == 0);
 
    REQUIRE(b.boundingRect() == QRectF(0,0,0,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));
 

	
 
    // 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));
 

	
 
    // 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));
 

	
 
    // 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));
 

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

	
 
TEST_CASE("ChunkedBuffer accessing data", "[memory]")
 
{
 
    ChunkedBuffer b;
 

	
 
    // prepare data
 
    double samples[CHUNK_SIZE*3];
 
    samples[0] = 10;
 
    samples[10] = 20;
 
    samples[CHUNK_SIZE-1] = 30;
 
    samples[CHUNK_SIZE] = 40;
 
    samples[CHUNK_SIZE+1] = 50;
 
    samples[CHUNK_SIZE*2-1] = 60;
 
    samples[CHUNK_SIZE*3-1] = 70;
 

	
 
    // test
 
    b.addSamples(samples, CHUNK_SIZE*3);
 

	
 
    REQUIRE(b.size() == CHUNK_SIZE*3);
 
    REQUIRE(b.sample(0) == 10);
 
    REQUIRE(b.sample(10) == 20);
 
    REQUIRE(b.sample(CHUNK_SIZE-1) == 30);
 
    REQUIRE(b.sample(CHUNK_SIZE) == 40);
 
    REQUIRE(b.sample(CHUNK_SIZE+1) == 50);
 
    REQUIRE(b.sample(CHUNK_SIZE*2-1) == 60);
 
    REQUIRE(b.sample(CHUNK_SIZE*3-1) == 70);
 
}
0 comments (0 inline, 0 general)