Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 43 additions & 14 deletions src/simplnx/DataStructure/AbstractDataStore.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

#include <nonstd/span.hpp>

#include <algorithm>
#include <compare>
#include <iterator>
#include <vector>
Expand Down Expand Up @@ -410,6 +409,22 @@ class AbstractDataStore : public IDataStore
*/
virtual void setValue(usize index, value_type value) = 0;

/**
* @brief Reads a contiguous range of values from the DataStore into a buffer.
* Reads buffer.size() elements starting from startIndex.
* @param startIndex The first flat element index to read from
* @param buffer Span to write values into; buffer.size() determines count
*/
virtual void getValues(usize startIndex, nonstd::span<T> buffer) const = 0;

/**
* @brief Writes a contiguous range of values from a buffer into the DataStore.
* Writes buffer.size() elements starting at startIndex.
* @param startIndex The first flat element index to write to
* @param buffer Span of values to write; buffer.size() determines count
*/
virtual void setValues(usize startIndex, nonstd::span<const T> buffer) = 0;

/**
* @brief Returns the value found at the specified index of the DataStore.
* This cannot be used to edit the value found at the specified index.
Expand Down Expand Up @@ -584,7 +599,10 @@ class AbstractDataStore : public IDataStore
*/
virtual void fill(value_type value)
{
std::fill(begin(), end(), value);
for(usize i = 0; i < getSize(); i++)
{
setValue(i, value);
}
}

/**
Expand All @@ -599,7 +617,10 @@ class AbstractDataStore : public IDataStore
{
return false;
}
std::copy(other.begin(), other.end(), begin());
for(usize i = 0; i < getSize(); i++)
{
setValue(i, other.getValue(i));
}
return true;
}

Expand Down Expand Up @@ -677,10 +698,7 @@ class AbstractDataStore : public IDataStore
totalSrcTuples * sourceNumComponents, destTupleOffset * numComponents, getSize()));
}

auto srcBegin = source.begin() + (srcTupleOffset * sourceNumComponents);
auto srcEnd = srcBegin + (totalSrcTuples * sourceNumComponents);
auto dstBegin = begin() + (destTupleOffset * numComponents);
std::copy(srcBegin, srcEnd, dstBegin);
copyFromImpl(destTupleOffset * numComponents, source, srcTupleOffset * sourceNumComponents, totalSrcTuples * sourceNumComponents);
return {};
}

Expand Down Expand Up @@ -743,13 +761,8 @@ class AbstractDataStore : public IDataStore
throw std::runtime_error(ss);
}

index_type numComponents = getNumberOfComponents();
index_type offset = tupleIndex * numComponents;
usize count = values.size();
for(usize i = 0; i < count; i++)
{
setValue(offset + i, values[i]);
}
index_type offset = tupleIndex * getNumberOfComponents();
setValues(offset, values);
}

/**
Expand Down Expand Up @@ -962,6 +975,22 @@ class AbstractDataStore : public IDataStore
virtual Result<> writeHdf5(HDF5::DatasetIO& dataset) const = 0;

protected:
/**
* @brief Performs the actual data transfer for copyFrom after bounds checking.
* Subclasses can override to provide optimized implementations.
* @param dstStartIndex Flat element index to start writing at
* @param source Source data store to copy from
* @param srcStartIndex Flat element index to start reading from
* @param totalElements Number of elements to copy
*/
virtual void copyFromImpl(usize dstStartIndex, const AbstractDataStore& source, usize srcStartIndex, usize totalElements)
{
for(usize i = 0; i < totalElements; i++)
{
setValue(dstStartIndex + i, source.getValue(srcStartIndex + i));
}
}

/**
* @brief Default constructor
*/
Expand Down
63 changes: 63 additions & 0 deletions src/simplnx/DataStructure/DataStore.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,60 @@ class DataStore : public AbstractDataStore<T>
std::swap(m_Data.get()[index1], m_Data.get()[index2]);
}

/**
* @brief Reads a contiguous range of values using memcpy.
* @param startIndex The first flat element index to read from
* @param buffer Span to write values into
*/
void getValues(usize startIndex, nonstd::span<T> buffer) const override
{
const usize count = buffer.size();
if(startIndex + count > this->getSize())
{
throw std::out_of_range(fmt::format("DataStore::getValues: range [{}, {}) exceeds size {}", startIndex, startIndex + count, this->getSize()));
}
std::copy(m_Data.get() + startIndex, m_Data.get() + startIndex + count, buffer.data());
}

/**
* @brief Writes a contiguous range of values into the DataStore.
* @param startIndex The first flat element index to write to
* @param buffer Span of values to write
*/
void setValues(usize startIndex, nonstd::span<const T> buffer) override
{
const usize count = buffer.size();
if(startIndex + count > this->getSize())
{
throw std::out_of_range(fmt::format("DataStore::setValues: range [{}, {}) exceeds size {}", startIndex, startIndex + count, this->getSize()));
}
std::copy(buffer.begin(), buffer.end(), m_Data.get() + startIndex);
}

/**
* @brief Fills the DataStore with the specified value using direct array access.
* @param value
*/
void fill(value_type value) override
{
std::fill_n(m_Data.get(), this->getSize(), value);
}

/**
* @brief Copies data from another AbstractDataStore using direct array access.
* @param other The source AbstractDataStore to copy from
* @return bool True if the copy succeeded
*/
bool copy(const AbstractDataStore<T>& other) override
{
if(this->getSize() != other.getSize())
{
return false;
}
other.getValues(0, nonstd::span<T>(m_Data.get(), this->getSize()));
return true;
}

/**
* @brief Returns a deep copy of the data store and all its data.
* @return std::unique_ptr<IDataStore>
Expand Down Expand Up @@ -647,6 +701,15 @@ class DataStore : public AbstractDataStore<T>
return upperBounds;
}

protected:
/**
* @brief Optimized data transfer for copyFrom using direct array access.
*/
void copyFromImpl(usize dstStartIndex, const AbstractDataStore<T>& source, usize srcStartIndex, usize totalElements) override
{
source.getValues(srcStartIndex, nonstd::span<T>(m_Data.get() + dstStartIndex, totalElements));
}

private:
ShapeType m_ComponentShape;
ShapeType m_TupleShape;
Expand Down
16 changes: 16 additions & 0 deletions src/simplnx/DataStructure/EmptyDataStore.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,22 @@ class EmptyDataStore : public AbstractDataStore<T>
throw std::runtime_error("EmptyDataStore::setValue() is not implemented");
}

/**
* @brief Throws an exception because this should never be called.
*/
void getValues(usize startIndex, nonstd::span<T> buffer) const override
{
throw std::runtime_error("EmptyDataStore::getValues() is not implemented");
}

/**
* @brief Throws an exception because this should never be called.
*/
void setValues(usize startIndex, nonstd::span<const T> buffer) override
{
throw std::runtime_error("EmptyDataStore::setValues() is not implemented");
}

/**
* @brief Throws an exception because this should never be called. The
* EmptyDataStore class contains no data other than its target getSize.
Expand Down
Loading
Loading