Added boundary check functions to clean up the code a bit

This commit is contained in:
Digital Artifex
2026-06-08 07:16:25 -04:00
parent e309107f4d
commit 39a06e0e8c
@@ -26,12 +26,12 @@
#include "komplex_global.h"
/**
* @brief The SlidingCacheControllerNotifier class
* @brief The SlidingCacheNotifier class
*
* Qt does not support templated QObjects. Pushing it to a notifier class
* that the template can inherit fixes this
*/
class KOMPLEX_EXPORT SlidingCacheControllerNotifier : public QObject
class KOMPLEX_EXPORT SlidingCacheNotifier : public QObject
{
Q_OBJECT
signals:
@@ -44,11 +44,11 @@ signals:
* This minimizes the number of API calls required to serve paged data
*/
template <typename T>
class KOMPLEX_EXPORT SlidingCacheController : public SlidingCacheControllerNotifier
class KOMPLEX_EXPORT SlidingCacheController : public SlidingCacheNotifier
{
public:
explicit SlidingCacheController()
explicit SlidingCacheController() : SlidingCacheNotifier{}
{
m_cache.reserve(SLIDING_CACHE_WINDOW_SIZE);
}
@@ -60,10 +60,10 @@ public:
/**
* @brief setFetch
*
* Used to set the fetch method for the cache controller. Method should return a QList
* of CacheObjects based on the offset and limit provided. CacheObject must derive from
* QObject
*
* @param fetch
*/
auto setFetch(
@@ -81,38 +81,18 @@ public:
* @return CacheObject* or nullptr
*/
[[nodiscard]]
auto at(qsizetype index) const -> T*
auto at(qsizetype index) const -> T
{
//OOB check for expected index
if (index < 0 ||
(m_totalCount != std::numeric_limits<qsizetype>::infinity() &&
index >= m_totalCount))
if(!slideWindow(index))
{
return nullptr;
return {};
}
while (index >= m_windowOffset + (SLIDING_CACHE_WINDOW_SIZE - SLIDING_CACHE_PREFETCH_THRESHOLD))
{
if(!slideForward())
{
break;
}
}
qsizetype internalIndex = trueIndex(index);
while (index <= m_windowOffset - (SLIDING_CACHE_WINDOW_SIZE - SLIDING_CACHE_PREFETCH_THRESHOLD))
if(!internalBoundaryCheck(index))
{
if(!slideBackward())
{
break;
}
}
index = trueIndex(index);
//OOB check for actual index
if(index < 0 || index >= m_cache.count())
{
return nullptr;
return {};
}
return m_cache.at(index);
@@ -127,21 +107,24 @@ public:
* @return
*/
[[nodiscard]]
auto chunk(qsizetype index, qsizetype count) -> QList<T*>
auto chunk(qsizetype index, qsizetype count) -> QList<T>
{
QList<T*> dataChunk;
if(!externalBoundaryCheck(index))
{
return {};
}
QList<T> dataChunk;
for(qsizetype i = index; i < count; ++i)
{
T* data = at(i);
T data = at(i);
if(data == nullptr)
if(data != T{})
{
break;
}
dataChunk.append(data);
}
}
return dataChunk;
}
@@ -178,10 +161,78 @@ protected:
return;
m_totalCount = count;
Q_EMIT static_cast<SlidingCacheControllerNotifier*>(this)->countChanged();
Q_EMIT static_cast<SlidingCacheNotifier*>(this)->countChanged();
}
private:
/**
* @brief externalBoundaryCheck
*
* Checks if the index is within the known bounds of the external
* dataset
* @param index
* @return True if index is within the external dataset boundary
* OR an initial fetch has not been performed.
*/
auto externalBoundaryCheck(qsizetype index) -> bool
{
return !(
index < 0 ||
(
m_totalCount != std::numeric_limits<qsizetype>::infinity() &&
index >= m_totalCount
)
);
}
/**
* @brief internalBoundaryCheck
*
* Checks if the index is within the currently cached dataset
* @param index
* @return True if index is within the internal dataset boundary
*/
auto internalBoundaryCheck(qsizetype index) -> bool
{
return (
index > 0 &&
index < m_cache.count()
);
}
/**
* @brief slideWindow
*
* Slides the current data window to the provided index
* @param index
* @return
*/
auto slideWindow(qsizetype index) -> bool
{
if (!externalBoundaryCheck(index))
{
return false;
}
while (index >= m_windowOffset + (SLIDING_CACHE_WINDOW_SIZE - SLIDING_CACHE_PREFETCH_THRESHOLD))
{
if(!slideForward())
{
return false;
}
}
while (index <= m_windowOffset - (SLIDING_CACHE_WINDOW_SIZE - SLIDING_CACHE_PREFETCH_THRESHOLD))
{
if(!slideBackward())
{
return false;
}
}
return true;
}
/**
* @brief slideForward
* Attempts to slide the cache window forward