Skip to content

Commit

Permalink
Add emberAfMetadataStructureGeneration for codegen data model. (#36104
Browse files Browse the repository at this point in the history
)

CodegenDataModel is using caching to speed up queries on clusters.
However dynamic endpoints can be created/removed at will and in those
cases old cluster pointers should not be re-used.
  • Loading branch information
andy31415 authored Oct 17, 2024
1 parent d7f99c7 commit e150e06
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -619,16 +619,18 @@ std::optional<unsigned> CodegenDataModelProvider::TryFindAttributeIndex(const Em

const EmberAfCluster * CodegenDataModelProvider::FindServerCluster(const ConcreteClusterPath & path)
{
// cache things
if (mPreviouslyFoundCluster.has_value() && (mPreviouslyFoundCluster->path == path))
if (mPreviouslyFoundCluster.has_value() && (mPreviouslyFoundCluster->path == path) &&
(mEmberMetadataStructureGeneration == emberAfMetadataStructureGeneration()))

{
return mPreviouslyFoundCluster->cluster;
}

const EmberAfCluster * cluster = emberAfFindServerCluster(path.mEndpointId, path.mClusterId);
if (cluster != nullptr)
{
mPreviouslyFoundCluster = std::make_optional<ClusterReference>(path, cluster);
mPreviouslyFoundCluster = std::make_optional<ClusterReference>(path, cluster);
mEmberMetadataStructureGeneration = emberAfMetadataStructureGeneration();
}
return cluster;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ class CodegenDataModelProvider : public chip::app::DataModel::Provider
ClusterReference(const ConcreteClusterPath p, const EmberAfCluster * c) : path(p), cluster(c) {}
};
std::optional<ClusterReference> mPreviouslyFoundCluster;
unsigned mEmberMetadataStructureGeneration = 0;

/// Finds the specified ember cluster
///
Expand Down
13 changes: 13 additions & 0 deletions src/app/util/attribute-storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ uint8_t singletonAttributeData[ACTUAL_SINGLETONS_SIZE];

uint16_t emberEndpointCount = 0;

/// Determines a incremental unique index for ember
/// metadata that is increased whenever a structural change is made to the
/// ember metadata (e.g. changing dynamic endpoints or enabling/disabling endpoints)
unsigned emberMetadataStructureGeneration = 0;

// If we have attributes that are more than 4 bytes, then
// we need this data block for the defaults
#if (defined(GENERATED_DEFAULTS) && GENERATED_DEFAULTS_COUNT)
Expand Down Expand Up @@ -315,6 +320,7 @@ CHIP_ERROR emberAfSetDynamicEndpoint(uint16_t index, EndpointId id, const EmberA
// Now enable the endpoint.
emberAfEndpointEnableDisable(id, true);

emberMetadataStructureGeneration++;
return CHIP_NO_ERROR;
}

Expand All @@ -332,6 +338,7 @@ EndpointId emberAfClearDynamicEndpoint(uint16_t index)
emAfEndpoints[index].endpoint = kInvalidEndpointId;
}

emberMetadataStructureGeneration++;
return ep;
}

Expand Down Expand Up @@ -944,9 +951,15 @@ bool emberAfEndpointEnableDisable(EndpointId endpoint, bool enable)
emberAfGlobalInteractionModelAttributesChangedListener());
}

emberMetadataStructureGeneration++;
return true;
}

unsigned emberAfMetadataStructureGeneration()
{
return emberMetadataStructureGeneration;
}

// Returns the index of a given endpoint. Does not consider disabled endpoints.
uint16_t emberAfIndexFromEndpoint(EndpointId endpoint)
{
Expand Down
8 changes: 8 additions & 0 deletions src/app/util/attribute-storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,14 @@ void emberAfAttributeChanged(chip::EndpointId endpoint, chip::ClusterId clusterI
/// any cluster data versions.
void emberAfEndpointChanged(chip::EndpointId endpoint, chip::app::AttributesChangedListener * listener);

/// Maintains a increasing index of structural changes within ember
/// that determine if existing "indexes" and metadata pointers within ember
/// are still valid or not.
///
/// Changes to metadata structure (e.g. endpoint enable/disable and dynamic endpoint changes)
/// are reflected in this generation count changing.
unsigned emberAfMetadataStructureGeneration();

namespace chip {
namespace app {

Expand Down
12 changes: 10 additions & 2 deletions src/app/util/mock/attribute-storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ using namespace Clusters::Globals::Attributes;

namespace {

DataVersion dataVersion = 0;
const MockNodeConfig * mockConfig = nullptr;
unsigned metadataStructureGeneration = 0;
DataVersion dataVersion = 0;
const MockNodeConfig * mockConfig = nullptr;

const MockNodeConfig & DefaultMockNodeConfig()
{
Expand Down Expand Up @@ -342,6 +343,11 @@ void emberAfAttributeChanged(EndpointId endpoint, ClusterId clusterId, Attribute
listener->MarkDirty(AttributePathParams(endpoint, clusterId, attributeId));
}

unsigned emberAfMetadataStructureGeneration()
{
return metadataStructureGeneration;
}

namespace chip {
namespace app {

Expand Down Expand Up @@ -494,12 +500,14 @@ CHIP_ERROR ReadSingleMockClusterData(FabricIndex aAccessingFabricIndex, const Co

void SetMockNodeConfig(const MockNodeConfig & config)
{
metadataStructureGeneration++;
mockConfig = &config;
}

/// Resets the mock attribute storage to the default configuration.
void ResetMockNodeConfig()
{
metadataStructureGeneration++;
mockConfig = nullptr;
}

Expand Down

0 comments on commit e150e06

Please sign in to comment.