Skip to content

Commit

Permalink
Added support for integer type master time channels. #101
Browse files Browse the repository at this point in the history
  • Loading branch information
ihedvall committed Aug 18, 2024
1 parent 20c135d commit b56f9ea
Show file tree
Hide file tree
Showing 8 changed files with 307 additions and 46 deletions.
2 changes: 1 addition & 1 deletion include/mdf/iblock.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class IBlock {
/** \brief Returns the block type.
*
* The block type is 2 character string for example 'AT' and 'DT'. In MDF 4,
* the block type is actual 4 character but this function removes
* the block type is actually 4 characters but this function removes
* the two first characters.
* @return Block type (2 characters length).
*/
Expand Down
28 changes: 26 additions & 2 deletions include/mdf/ichannel.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ class IChannel : public IBlock {
* @param values 1-Dimensional list of array values.
*/
template<typename T>
void SetChannelValues(const std::vector<T>& value_array);
void SetChannelValues(const std::vector<T>& values);

/** \brief Internally used function mainly for fetching VLSD index values.
*
Expand Down Expand Up @@ -492,6 +492,29 @@ class IChannel : public IBlock {
value = std::to_string(sample);
return true;
}

/** \brief Defines if the master channel time should be calculated or not.
*
* If the channel is a master channel and the channel sync type is time,
* this option defines if its channel value should be calculated from
* the MdfWriter sample queue absolute time. Not used for reader applications.
*
* Default is the option set to true i.e. the channel value will be
* calculated from the absolute time in the writers sample queue. If
* it set to false, the user is responsible to set the channels value.
* @param calculate_master If set tp false, the user must set the channel value.
*/
void CalculateMasterTime(bool calculate_master) {
calculate_master_time_ = calculate_master;
}

/** \brief Defines if the master channel time is calculated or user defined.
*
* @return True means that the master channel is calculated.
*/
[[nodiscard]] bool CalculateMasterTime() const {
return calculate_master_time_;
}
protected:


Expand Down Expand Up @@ -543,9 +566,11 @@ class IChannel : public IBlock {
/** \brief Support function that sets array values */
virtual void SetByteArray(const std::vector<uint8_t> &value, bool valid);


private:

mutable uint64_t vlsd_record_id_ = 0; ///< Used to fix the VLSD CG block.
bool calculate_master_time_ = true; ///< If true, the master time channel will be calculated.
};

template <typename T>
Expand Down Expand Up @@ -690,7 +715,6 @@ void IChannel::SetChannelValue(const T &value, bool valid,
}
break;


default:
SetValid(false, array_index);
break;
Expand Down
1 change: 0 additions & 1 deletion mdflib/src/dgrange.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
/** \file
* This file define the DG range support class.
*/
#pragma once

#include "dgrange.h"
#include "mdf/ichannelgroup.h"
Expand Down
72 changes: 71 additions & 1 deletion mdflib/src/ichannel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <string>

#include "bigbuffer.h"
#include "half.hpp"
// #include "half.hpp"
#include "littlebuffer.h"
#include "dbchelper.h"
#include "mdf/ichannelgroup.h"
Expand Down Expand Up @@ -860,6 +860,76 @@ void IChannel::SetTimestamp(double timestamp,
const size_t bytes = BitCount() / 8;

switch (DataType()) {
case ChannelDataType::UnsignedIntegerBe:
if (timestamp < 0) {
timestamp = 0;
}
if (bytes == 1) {
const BigBuffer data(static_cast<uint8_t>(timestamp));
memcpy(record_buffer.data() + ByteOffset(), data.data(), bytes);
} else if (bytes == 2) {
const BigBuffer data(static_cast<uint16_t>(timestamp));
memcpy(record_buffer.data() + ByteOffset(), data.data(), bytes);
} else if (bytes == 4) {
const BigBuffer data(static_cast<uint32_t>(timestamp));
memcpy(record_buffer.data() + ByteOffset(), data.data(), bytes);
} else if (bytes == 8) {
const BigBuffer data(static_cast<uint64_t>(timestamp));
memcpy(record_buffer.data() + ByteOffset(), data.data(), bytes);
}
break;

case ChannelDataType::UnsignedIntegerLe:
if (timestamp < 0) {
timestamp = 0;
}
if (bytes == 1) {
const LittleBuffer data(static_cast<uint8_t>(timestamp));
memcpy(record_buffer.data() + ByteOffset(), data.data(), bytes);
} else if (bytes == 2) {
const LittleBuffer data(static_cast<uint16_t>(timestamp));
memcpy(record_buffer.data() + ByteOffset(), data.data(), bytes);
} else if (bytes == 4) {
const LittleBuffer data(static_cast<uint32_t>(timestamp));
memcpy(record_buffer.data() + ByteOffset(), data.data(), bytes);
} else if (bytes == 8) {
const LittleBuffer data(static_cast<uint64_t>(timestamp));
memcpy(record_buffer.data() + ByteOffset(), data.data(), bytes);
}
break;

case ChannelDataType::SignedIntegerBe:
if (bytes == 1) {
const BigBuffer data(static_cast<int8_t>(timestamp));
memcpy(record_buffer.data() + ByteOffset(), data.data(), bytes);
} else if (bytes == 2) {
const BigBuffer data(static_cast<int16_t>(timestamp));
memcpy(record_buffer.data() + ByteOffset(), data.data(), bytes);
} else if (bytes == 4) {
const BigBuffer data(static_cast<int32_t>(timestamp));
memcpy(record_buffer.data() + ByteOffset(), data.data(), bytes);
} else if (bytes == 8) {
const BigBuffer data(static_cast<int64_t>(timestamp));
memcpy(record_buffer.data() + ByteOffset(), data.data(), bytes);
}
break;

case ChannelDataType::SignedIntegerLe:
if (bytes == 1) {
const LittleBuffer data(static_cast<int8_t>(timestamp));
memcpy(record_buffer.data() + ByteOffset(), data.data(), bytes);
} else if (bytes == 2) {
const LittleBuffer data(static_cast<int16_t>(timestamp));
memcpy(record_buffer.data() + ByteOffset(), data.data(), bytes);
} else if (bytes == 4) {
const LittleBuffer data(static_cast<int32_t>(timestamp));
memcpy(record_buffer.data() + ByteOffset(), data.data(), bytes);
} else if (bytes == 8) {
const LittleBuffer data(static_cast<int64_t>(timestamp));
memcpy(record_buffer.data() + ByteOffset(), data.data(), bytes);
}
break;

case ChannelDataType::FloatLe:
if (bytes == 4) {
const LittleBuffer data(static_cast<float>(timestamp));
Expand Down
12 changes: 6 additions & 6 deletions mdflib/src/mdfwriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ void MdfWriter::SaveSample(const IChannelGroup& group, uint64_t time) {
const auto itr_master = master_channels_.find(group.RecordId());
const auto* master =
itr_master == master_channels_.cend() ? nullptr : itr_master->second;
if (master != nullptr) {
if (master != nullptr && master->CalculateMasterTime()) {
auto rel_ns = static_cast<int64_t>(sample.timestamp);
rel_ns -= static_cast<int64_t>(start_time_);
const double rel_s = static_cast<double>(rel_ns) / 1'000'000'000.0;
Expand All @@ -212,7 +212,7 @@ void MdfWriter::SaveCanMessage(const IChannelGroup& group, uint64_t time,
const auto itr_master = master_channels_.find(group.RecordId());
const auto* master = itr_master == master_channels_.cend() ?
nullptr : itr_master->second;
if (master != nullptr) {
if (master != nullptr && master->CalculateMasterTime()) {
auto rel_ns = static_cast<int64_t>(sample.timestamp);
rel_ns -= static_cast<int64_t>(start_time_);
const double rel_s = static_cast<double>(rel_ns) / 1'000'000'000.0;
Expand Down Expand Up @@ -279,14 +279,14 @@ void MdfWriter::RecalculateTimeMaster() {
if (itr_ch == master_channels_.end()) {
continue;
}
const auto* master = itr_ch->second;
if (master == nullptr || !master->CalculateMasterTime() ) {
continue;
}
auto rel_ns = static_cast<int64_t>(sample.timestamp);
rel_ns -= static_cast<int64_t>(start_time_);
const double rel_s = static_cast<double>(rel_ns) / 1'000'000'000.0;

const auto* master = itr_ch->second;
if (master == nullptr) {
continue;
}
master->SetTimestamp(rel_s, sample.record_buffer);
}
}
Expand Down
3 changes: 2 additions & 1 deletion mdflib_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ add_executable(test_mdf
src/testchannel.cpp
src/testchannelarray.cpp
src/testchannelarray.h
src/testxtensor.cpp)
src/testxtensor.cpp
src/testqueue.cpp)

target_include_directories(test_mdf PRIVATE ../include ../mdflib/src)
target_include_directories(test_mdf PRIVATE ${XTENSOR_INCLUDE_DIRS})
Expand Down
69 changes: 69 additions & 0 deletions mdflib_test/src/testqueue.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright 2024 Ingemar Hedvall
* SPDX-License-Identifier: MIT
*/

#include <gtest/gtest.h>
#include <list>
#include <deque>
#include <queue>
#include "mdf/samplerecord.h"
#include "mdf/mdfhelper.h"

using namespace mdf;


namespace mdf::test {

TEST(TestQueueSpeed, TestList) {
SampleRecord test_record;
test_record.timestamp = MdfHelper::NowNs();
test_record.record_id = 1;
test_record.record_buffer.resize(1000, 0);

std::cout << std::endl;
{
const uint64_t start_time = MdfHelper::NowNs();
std::list<SampleRecord> list;
for (size_t sample = 0; sample < 1'000'000; ++sample) {
list.push_back(test_record);
}
while (!list.empty()) {
list.pop_front();
}
const uint64_t run_time = MdfHelper::NowNs() - start_time;
std::cout << "List Run Time (ms): "
<< static_cast<double>(run_time) / 1'000'000 << std::endl;
}

{
const uint64_t start_time = MdfHelper::NowNs();
std::deque<SampleRecord> list;
for (size_t sample = 0; sample < 1'000'000; ++sample) {
list.push_back(test_record);
}
while (!list.empty()) {
list.pop_front();
}
const uint64_t run_time = MdfHelper::NowNs() - start_time;
std::cout << "Deque Run Time (ms): "
<< static_cast<double>(run_time) / 1'000'000 << std::endl;
}

{
const uint64_t start_time = MdfHelper::NowNs();
std::queue<SampleRecord> list;
for (size_t sample = 0; sample < 1'000'000; ++sample) {
list.push(test_record);
}
while (!list.empty()) {
list.pop();
}
const uint64_t run_time = MdfHelper::NowNs() - start_time;
std::cout << "Queue Run Time (ms): "
<< static_cast<double>(run_time) / 1'000'000 << std::endl;
}
std::cout << std::endl;
}

} // end namespace mdf::test
Loading

0 comments on commit b56f9ea

Please sign in to comment.