Changeset - c1dbdeb915ed
[Not reviewed]
longmem
0 1 7
Hasan Yavuz ÖZDERYA - 8 years ago 2017-07-15 11:28:20
hy@ozderya.net
adding experimental chunkbuffer code with tests
6 files changed:
0 comments (0 inline, 0 general)
CMakeLists.txt
Show inline comments
 
@@ -205,24 +205,31 @@ endif (UNIX)
 

	
 
# uninstalling
 
configure_file(
 
  "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
 
  "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
 
  @ONLY)
 

	
 
if (UNIX)
 
  add_custom_target(uninstall
 
    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
 
endif (UNIX)
 

	
 
# testing
 
set(ENABLE_TESTS false CACHE BOOL "Build tests.")
 
if (ENABLE_TESTS)
 
  enable_testing()
 
  add_subdirectory(tests)
 
endif ()
 

	
 
# packaging
 
include(BuildLinuxAppImage)
 

	
 
if (UNIX)
 
  set(CPACK_GENERATOR "DEB")
 
elseif (WIN32)
 
  set(CPACK_GENERATOR "NSIS")
 
endif (UNIX)
 

	
 
include(InstallRequiredSystemLibraries)
 

	
 
set(CPACK_PACKAGE_NAME "${PROGRAM_NAME}")
src/chunkedbuffer.cpp
Show inline comments
 
new file 100644
 
/*
 
  Copyright © 2017 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
 
  (at your option) any later version.
 

	
 
  serialplot is distributed in the hope that it will be useful,
 
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
  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
 
    addChunk();
 
}
 

	
 
~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 = chunk->last();
 
        if (chunk->isFull())
 
        {
 
            chunk = addChunk(); // 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;
 
}
 

	
 
DataChunk* ChunkedBuffer::addChunk()
 
{
 
    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
 
    ymin = chunks->first().min();
 
    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));
 
}
src/chunkedbuffer.h
Show inline comments
 
new file 100644
 
/*
 
  Copyright © 2017 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
 
  (at your option) any later version.
 

	
 
  serialplot is distributed in the hope that it will be useful,
 
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
  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/>.
 
*/
 

	
 
#ifndef CHUNKEDBUFFER_H
 
#define CHUNKEDBUFFER_H
 

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

	
 
#define CHUNK_SIZE (1024)
 

	
 
class ChunkedBuffer
 
{
 
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;
 

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

	
 
    QList<DataChunk*> chunks;
 
};
 

	
 

	
 
#endif // CHUNKEDBUFFER_H
src/datachunk.cpp
Show inline comments
 
new file 100644
 
/*
 
  Copyright © 2017 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
 
  (at your option) any later version.
 

	
 
  serialplot is distributed in the hope that it will be useful,
 
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
  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 <QtGlobal>
 

	
 
#include "datachunk.h"
 

	
 
DataChunk::DataChunk(size_t start, size_t capacity)
 
{
 
    _start = start;
 
    _capacity = capacity;
 
    _size = 0;
 
    _samples = new double[capacity];
 

	
 
    _min = 0;
 
    _max = 0;
 
    _sum = 0;
 
    _sumSquare = 0;
 
}
 

	
 
DataChunk::~DataChunk()
 
{
 
    delete[] _samples;
 
}
 

	
 
size_t DataChunk::start() const
 
{
 
    return _start;
 
}
 

	
 
size_t DataChunk::end() const
 
{
 
    return _start + _size;
 
}
 

	
 
bool DataChunk::isFull() const
 
{
 
    return left() == 0;
 
}
 

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

	
 
size_t DataChunk::capacity() const
 
{
 
    return _capacity;
 
}
 

	
 
size_t DataChunk::left() const
 
{
 
    return _capacity - _size;
 
}
 

	
 
double DataChunk::min() const
 
{
 
    return _min;
 
}
 

	
 
double DataChunk::max() const
 
{
 
    return _max;
 
}
 

	
 
double DataChunk::avg() const
 
{
 
    return _sum / _size;
 
}
 

	
 
double DataChunk::meanSquare() const
 
{
 
    return _sumSquare / _size;
 
}
 

	
 
double DataChunk::sample(size_t i) const
 
{
 
    Q_ASSERT(i <= _size);
 
    return _samples[i];
 
}
 

	
 
void DataChunk::addSamples(double* samples, size_t size)
 
{
 
    Q_ASSERT(size > 0 && size <= left());
 

	
 
    // start min&max values from first sample
 
    if (_size == 0)
 
    {
 
        _min = _max = samples[0];
 
    }
 

	
 
    for (unsigned i = 0; i < size; i++)
 
    {
 
        double newSample = samples[i];
 

	
 
        _samples[this->_size + i] = newSample;
 

	
 
        // update min/max and measurements
 
        if (newSample < _min)
 
        {
 
            _min = newSample;
 
        }
 
        else if (newSample > _max)
 
        {
 
            _max = newSample;
 
        }
 
        _sum += newSample;
 
        _sumSquare += newSample * newSample;
 
    }
 

	
 
    this->_size += size;
 

	
 
    Q_ASSERT(this->_size <= this->_capacity);
 
}
src/datachunk.h
Show inline comments
 
new file 100644
 
/*
 
  Copyright © 2017 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
 
  (at your option) any later version.
 

	
 
  serialplot is distributed in the hope that it will be useful,
 
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
  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/>.
 
*/
 

	
 
#ifndef DATACHUNK_H
 
#define DATACHUNK_H
 

	
 
class DataChunk
 
{
 
public:
 
    DataChunk(size_t start, size_t capacity);
 
    ~DataChunk();
 

	
 
    size_t start() const;       // index of first element
 
    size_t end() const;         // index after last element
 
    size_t size() const;        // fill size
 
    size_t capacity() const;    // set capacity
 
    bool isFull() const;
 
    size_t left() const;
 

	
 
    double min() const;
 
    double max() const;
 
    double avg() const;
 
    double meanSquare() const;
 

	
 
    void addSamples(double* samples, size_t size);
 
    double sample(size_t i) const;
 

	
 
private:
 
    size_t _start;
 
    size_t _capacity;
 
    size_t _size;
 

	
 
    double _min;
 
    double _max;
 
    double _sum;
 
    double _sumSquare;          // sum of squares
 

	
 
    double* _samples;
 
};
 

	
 
#endif // DATACHUNK_H
tests/CMakeLists.txt
Show inline comments
 
new file 100644
 
#
 
# Copyright © 2017 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
 
# (at your option) any later version.
 
#
 
# serialplot is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# 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/>.
 
#
 

	
 
# Find the QtWidgets library
 
find_package(Qt5Widgets)
 

	
 
include_directories("../src")
 

	
 
add_executable(Test EXCLUDE_FROM_ALL
 
  test.cpp ../src/datachunk.cpp)
 
add_test(NAME test1 COMMAND Test)
 
qt5_use_modules(Test Widgets)
 

	
 
set(CMAKE_CTEST_COMMAND ctest -V)
 
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})
 
add_dependencies(check Test)

Changeset was too big and was cut off... Show full diff anyway

0 comments (0 inline, 0 general)