mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 16:57:31 +01:00
98 lines
3.2 KiB
C++
98 lines
3.2 KiB
C++
#include "storage_expression_model_store.h"
|
|
|
|
namespace Shared {
|
|
|
|
StorageExpressionModelStore::StorageExpressionModelStore() :
|
|
m_firstMemoizedModelIndex(0)
|
|
{
|
|
}
|
|
|
|
int StorageExpressionModelStore::numberOfModels() const {
|
|
return Ion::Storage::sharedStorage()->numberOfRecordsWithExtension(modelExtension());
|
|
}
|
|
|
|
int StorageExpressionModelStore::numberOfDefinedModels() const {
|
|
int result = 0;
|
|
int i = 0;
|
|
StorageExpressionModel * m = modelAtIndex(i++);
|
|
while (!m->isNull()) {
|
|
if (m->isDefined()) {
|
|
result++;
|
|
}
|
|
m = modelAtIndex(i++);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
StorageExpressionModel * StorageExpressionModelStore::modelAtIndex(int i) const {
|
|
/* If the model index asked is out of the range of the memoized index, we
|
|
* translate the memoized models to include the model i at the closest
|
|
* extremity of the array. */
|
|
if (i >= m_firstMemoizedModelIndex+k_maxNumberOfMemoizedModels || i < m_firstMemoizedModelIndex) {
|
|
int deltaIndex = i >= m_firstMemoizedModelIndex + k_maxNumberOfMemoizedModels ? i - k_maxNumberOfMemoizedModels + 1 - m_firstMemoizedModelIndex : i - m_firstMemoizedModelIndex;
|
|
// Translate memoized models
|
|
for (int i = 0; i < k_maxNumberOfMemoizedModels-1; i++) {
|
|
int j = deltaIndex + i;
|
|
if (j >= 0 && j < k_maxNumberOfMemoizedModels) {
|
|
moveMemoizedModel(i, j);
|
|
} else {
|
|
// Fill new models with empty records
|
|
Ion::Storage::Record emptyRecord;
|
|
setMemoizedModelAtIndex(i, emptyRecord);
|
|
}
|
|
}
|
|
m_firstMemoizedModelIndex += deltaIndex;
|
|
}
|
|
assert(i-m_firstMemoizedModelIndex < k_maxNumberOfMemoizedModels);
|
|
uint32_t currentStorageChecksum = Ion::Storage::sharedStorage()->checksum();
|
|
/* We have to build a new model if:
|
|
* - the model has never been created
|
|
* - Storage changed since last built. For instance, if f(x) = A+x, if A
|
|
* changes, we need to unmemoize f. */
|
|
if (memoizedModelAtIndex(i-m_firstMemoizedModelIndex)->isNull() || currentStorageChecksum != m_storageChecksum) {
|
|
Ion::Storage::Record record = Ion::Storage::sharedStorage()->recordWithExtensionAtIndex(modelExtension(), i);
|
|
setMemoizedModelAtIndex(i-m_firstMemoizedModelIndex, record);
|
|
m_storageChecksum = currentStorageChecksum;
|
|
}
|
|
return memoizedModelAtIndex(i-m_firstMemoizedModelIndex);
|
|
}
|
|
|
|
StorageExpressionModel * StorageExpressionModelStore::definedModelAtIndex(int i) const {
|
|
assert(i >= 0 && i < numberOfDefinedModels());
|
|
int index = 0;
|
|
int currentModelIndex = 0;
|
|
StorageExpressionModel * m = modelAtIndex(currentModelIndex++);
|
|
while (!m->isNull()) {
|
|
assert(currentModelIndex <= numberOfModels());
|
|
if (m->isDefined()) {
|
|
if (i == index) {
|
|
return m;
|
|
}
|
|
index++;
|
|
}
|
|
m = modelAtIndex(currentModelIndex++);
|
|
}
|
|
assert(false);
|
|
return nullptr;
|
|
}
|
|
|
|
void StorageExpressionModelStore::removeAll() {
|
|
Ion::Storage::sharedStorage()->destroyRecordsWithExtension(modelExtension());
|
|
}
|
|
|
|
void StorageExpressionModelStore::removeModel(StorageExpressionModel * f) {
|
|
assert(f != nullptr);
|
|
f->destroy();
|
|
}
|
|
|
|
void StorageExpressionModelStore::tidy() {
|
|
int i = 0;
|
|
StorageExpressionModel * m = modelAtIndex(i++);
|
|
while (!m->isNull()) {
|
|
m->tidy();
|
|
m = modelAtIndex(i++);
|
|
}
|
|
}
|
|
|
|
}
|