diff --git a/apps/graph/storage_cartesian_function_store.cpp b/apps/graph/storage_cartesian_function_store.cpp index be6649b9a..258980c94 100644 --- a/apps/graph/storage_cartesian_function_store.cpp +++ b/apps/graph/storage_cartesian_function_store.cpp @@ -28,7 +28,7 @@ Ion::Storage::Record::ErrorStatus StorageCartesianFunctionStore::addEmptyModel() return error; } -void StorageCartesianFunctionStore::privateSetMemoizedModelAtIndex(int cacheIndex, Ion::Storage::Record record) const { +void StorageCartesianFunctionStore::setMemoizedModelAtIndex(int cacheIndex, Ion::Storage::Record record) const { assert(cacheIndex >= 0 && cacheIndex < k_maxNumberOfMemoizedModels); m_functions[cacheIndex] = StorageCartesianFunction(record); } diff --git a/apps/graph/storage_cartesian_function_store.h b/apps/graph/storage_cartesian_function_store.h index 1d5c080a9..3637109de 100644 --- a/apps/graph/storage_cartesian_function_store.h +++ b/apps/graph/storage_cartesian_function_store.h @@ -19,7 +19,7 @@ public: private: Ion::Storage::Record::ErrorStatus addEmptyModel() override; const char * modelExtension() const override { return Shared::GlobalContext::funcExtension; } - void privateSetMemoizedModelAtIndex(int cacheIndex, Ion::Storage::Record record) const override; + void setMemoizedModelAtIndex(int cacheIndex, Ion::Storage::Record record) const override; void moveMemoizedModel(int previousIndex, int nextIndex) const override; Shared::StorageExpressionModel * memoizedModelAtIndex(int cacheIndex) const override; mutable Shared::StorageCartesianFunction m_functions[k_maxNumberOfMemoizedModels]; diff --git a/apps/shared/storage_expression_model_store.cpp b/apps/shared/storage_expression_model_store.cpp index 6521b390a..8f2cb6116 100644 --- a/apps/shared/storage_expression_model_store.cpp +++ b/apps/shared/storage_expression_model_store.cpp @@ -25,16 +25,18 @@ int StorageExpressionModelStore::numberOfDefinedModels() const { } 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) { - // Change range of layout memoization 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) { - m_memoizedModelChecksum[i] = m_memoizedModelChecksum[j]; moveMemoizedModel(i, j); } else { + // Fill new models with empty records Ion::Storage::Record emptyRecord; setMemoizedModelAtIndex(i, emptyRecord); } @@ -42,10 +44,15 @@ StorageExpressionModel * StorageExpressionModelStore::modelAtIndex(int i) const m_firstMemoizedModelIndex += deltaIndex; } assert(i-m_firstMemoizedModelIndex < k_maxNumberOfMemoizedModels); - Ion::Storage::Record record = Ion::Storage::sharedStorage()->recordWithExtensionAtIndex(modelExtension(), i); - // Storage might have changed since last call - if (memoizedModelAtIndex(i-m_firstMemoizedModelIndex)->isNull() || m_memoizedModelChecksum[i-m_firstMemoizedModelIndex] != record.checksum()) { + 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); } @@ -87,9 +94,4 @@ void StorageExpressionModelStore::tidy() { } } -void StorageExpressionModelStore::setMemoizedModelAtIndex(int cacheIndex, Ion::Storage::Record record) const { - m_memoizedModelChecksum[cacheIndex] = record.isNull() ? 0 : record.checksum(); - privateSetMemoizedModelAtIndex(cacheIndex, record); -} - } diff --git a/apps/shared/storage_expression_model_store.h b/apps/shared/storage_expression_model_store.h index 5b5c63cd2..496514e14 100644 --- a/apps/shared/storage_expression_model_store.h +++ b/apps/shared/storage_expression_model_store.h @@ -31,11 +31,12 @@ protected: constexpr static int k_maxNumberOfMemoizedModels = 5; private: virtual const char * modelExtension() const = 0; - // Memoization of k_maxNumberOfMemoizedModels consecutive models + /* Memoization of k_maxNumberOfMemoizedModels consecutive models: + * stores memoize k_maxNumberOfMemoizedModels consecutive models from the + * m_firstMemoizedModelIndex. */ mutable int m_firstMemoizedModelIndex; - mutable uint32_t m_memoizedModelChecksum[k_maxNumberOfMemoizedModels]; - void setMemoizedModelAtIndex(int cacheIndex, Ion::Storage::Record) const; - virtual void privateSetMemoizedModelAtIndex(int cacheIndex, Ion::Storage::Record record) const = 0; + mutable uint32_t m_storageChecksum; + virtual void setMemoizedModelAtIndex(int cacheIndex, Ion::Storage::Record) const = 0; virtual void moveMemoizedModel(int previousIndex, int nextIndex) const = 0; virtual StorageExpressionModel * memoizedModelAtIndex(int cacheIndex) const = 0; };