Skip to content

Commit e0008d5

Browse files
committed
Addressed review comments
1 parent 871b16d commit e0008d5

File tree

5 files changed

+151
-121
lines changed

5 files changed

+151
-121
lines changed

src/darwin/Framework/CHIP/MTRDevice.mm

+49-45
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ - (void)_setDSTOffsets:(NSArray<MTRTimeSynchronizationClusterDSTOffsetStruct *>
675675
completion:setDSTOffsetResponseHandler];
676676
}
677677

678-
- (NSMutableArray<NSNumber *> *)arrayOfNumbersFromAttributeValue:(NSDictionary *)dataDictionary
678+
- (NSMutableArray<NSNumber *> *)arrayOfNumbersFromAttributeValue:(MTRDeviceDataValueDictionary)dataDictionary
679679
{
680680
if (![MTRArrayValueType isEqual:dataDictionary[MTRTypeKey]]) {
681681
return nil;
@@ -3040,35 +3040,43 @@ - (void)_removeClusters:(NSSet<MTRClusterPath *> *)clusterPathsToRemove
30403040

30413041
for (MTRClusterPath * path in clusterPathsToRemove) {
30423042
[_persistedClusterData removeObjectForKey:path];
3043-
[_persistedClusters removeObject:path];
30443043
[_clusterDataToPersist removeObjectForKey:path];
30453044
[self.deviceController.controllerDataStore clearStoredClusterDataForNodeID:self.nodeID endpointID:path.endpoint clusterID:path.cluster];
30463045
}
30473046
}
30483047

3049-
- (void)_removeAttributes:(NSSet<NSNumber *> *)attributes fromCluster:(MTRClusterPath *)clusterPath
3048+
- (void)_removeClustersFromCache:(NSSet<MTRClusterPath *> *)clusterPathsToRemove
30503049
{
3051-
if (toBeRemovedAttributes == nil || clusterPathToRemoveAttributesFrom == nil) {
3052-
return;
3050+
os_unfair_lock_assert_owner(&self->_lock);
3051+
3052+
[_persistedClusters minusSet:clusterPathsToRemove];
3053+
3054+
for (MTRClusterPath * path in clusterPathsToRemove) {
3055+
[_persistedClusterData removeObjectForKey:path];
3056+
[_clusterDataToPersist removeObjectForKey:path];
30533057
}
3058+
}
3059+
3060+
- (void)_removeAttributes:(NSSet<NSNumber *> *)attributes fromCluster:(MTRClusterPath *)clusterPath
3061+
{
30543062
os_unfair_lock_assert_owner(&self->_lock);
30553063

3056-
for (NSNumber * attribute in toBeRemovedAttributes) {
3057-
[self _removeCachedAttribute:attribute fromCluster:clusterPathToRemoveAttributesFrom];
3064+
for (NSNumber * attribute in attributes) {
3065+
[self _removeCachedAttribute:attribute fromCluster:clusterPath];
30583066
}
30593067
// Just clear out the NSCache entry for this cluster, so we'll load it from storage as needed.
3060-
[_persistedClusterData removeObjectForKey:clusterPathToRemoveAttributesFrom];
3061-
[self.deviceController.controllerDataStore clearStoredClusterDataForNodeID:self.nodeID endpointID:clusterPathToRemoveAttributesFrom.endpoint clusterID:clusterPathToRemoveAttributesFrom.cluster];
3068+
[_persistedClusterData removeObjectForKey:clusterPath];
3069+
[self.deviceController.controllerDataStore removeAttributes:attributes fromCluster:clusterPath forNodeID:self.nodeID];
30623070
}
30633071

3064-
- (void)_pruneEndpointsIn:(NSDictionary *)previousPartsListValue
3065-
missingFrom:(NSDictionary *)newPartsListValue
3072+
- (void)_pruneEndpointsIn:(MTRDeviceDataValueDictionary)previousPartsListValue
3073+
missingFrom:(MTRDeviceDataValueDictionary)newPartsListValue
30663074
{
30673075
// If the parts list changed and one or more endpoints were removed, remove all the
30683076
// clusters for all those endpoints from our data structures.
30693077
// Also remove those endpoints from the data store.
3070-
NSMutableSet * toBeRemovedEndpoints = [NSMutableSet setWithArray:[self arrayOfNumbersFromAttributeValue:[self _dataValueWithoutDataVersion:previousPartsListValue]]];
3071-
NSSet * endpointsOnDevice = [NSSet setWithArray:[self arrayOfNumbersFromAttributeValue:newPartsListValue]];
3078+
NSMutableSet<NSNumber*> * toBeRemovedEndpoints = [NSMutableSet setWithArray:[self arrayOfNumbersFromAttributeValue:previousPartsListValue]];
3079+
NSSet<NSNumber *> * endpointsOnDevice = [NSSet setWithArray:[self arrayOfNumbersFromAttributeValue:newPartsListValue]];
30723080
[toBeRemovedEndpoints minusSet:endpointsOnDevice];
30733081

30743082
for (NSNumber * endpoint in toBeRemovedEndpoints) {
@@ -3078,75 +3086,71 @@ - (void)_pruneEndpointsIn:(NSDictionary *)previousPartsListValue
30783086
[clusterPathsToRemove addObject:path];
30793087
}
30803088
}
3081-
[self _removeClusters:[clusterPathsToRemove copy]];
3082-
[self.deviceController.controllerDataStore removeEndpointFromEndpointIndex:endpoint forNodeID:self.nodeID];
3089+
[self _removeClustersFromCache:clusterPathsToRemove];
3090+
[self.deviceController.controllerDataStore clearStoredClusterDataForNodeID:self.nodeID endpointID:endpoint];
30833091
}
30843092
}
30853093

3086-
- (void)_pruneOrphanedClusters:(MTRAttributePath *)attributePath
3087-
previousServerListValue:(NSDictionary *)previousServerListValue
3088-
newServerListValue:(NSDictionary *)newServerListValue
3094+
- (void)_pruneClustersIn:(MTRDeviceDataValueDictionary)previousServerListValue
3095+
missingFrom:(MTRDeviceDataValueDictionary)newServerListValue
3096+
forEndpoint:(NSNumber *)endpointID
30893097
{
30903098
// If the server list changed and clusters were removed, remove those clusters from our data structures.
30913099
// Also remove it from the data store.
3092-
NSMutableSet<NSNumber *> * toBeRemovedClusters = [NSMutableSet setWithArray:[self arrayOfNumbersFromAttributeValue:[self _dataValueWithoutDataVersion:previousServerListValue]]];
3100+
NSMutableSet<NSNumber *> * toBeRemovedClusters = [NSMutableSet setWithArray:[self arrayOfNumbersFromAttributeValue:previousServerListValue]];
30933101
NSSet<NSNumber *> * clustersStillOnEndpoint = [NSSet setWithArray:[self arrayOfNumbersFromAttributeValue:newServerListValue]];
30943102
[toBeRemovedClusters minusSet:clustersStillOnEndpoint];
30953103

30963104
NSMutableSet<MTRClusterPath *> * clusterPathsToRemove = [[NSMutableSet alloc] init];
30973105
for (NSNumber * cluster in toBeRemovedClusters) {
30983106
for (MTRClusterPath * path in _persistedClusters) {
3099-
if ([path.endpoint isEqualToNumber:attributePath.endpoint] && [path.cluster isEqualToNumber:cluster]) {
3107+
if ([path.endpoint isEqualToNumber:endpointID] && [path.cluster isEqualToNumber:cluster]) {
31003108
[clusterPathsToRemove addObject:path];
31013109
}
31023110
}
31033111
}
3104-
[self _removeClusters:[clusterPathsToRemove copy]];
3112+
[self _removeClusters:clusterPathsToRemove];
31053113
}
31063114

3107-
- (void)_pruneOrphanedAttributes:(MTRAttributePath *)attributePath
3108-
newAttributeListValue:(NSDictionary *)newAttributeListValue
3115+
- (void)_pruneAttributesIn:(MTRDeviceDataValueDictionary)previousAttributeListValue
3116+
missingFrom:(MTRDeviceDataValueDictionary)newAttributeListValue
3117+
forCluster:(MTRClusterPath *)clusterPath
31093118
{
31103119
// If the attribute list changed and attributes were removed, remove the attributes from our
31113120
// data structures.
3112-
NSMutableSet<NSNumber *> * toBeRemovedAttributes = [NSMutableSet setWithArray:[self arrayOfNumbersFromAttributeValue:[self _cachedAttributeValueForPath:attributePath]]];
3121+
NSMutableSet<NSNumber *> * toBeRemovedAttributes = [NSMutableSet setWithArray:[self arrayOfNumbersFromAttributeValue:previousAttributeListValue]];
31133122
NSSet<NSNumber *> * attributesStillInCluster = [NSSet setWithArray:[self arrayOfNumbersFromAttributeValue:newAttributeListValue]];
31143123

31153124
[toBeRemovedAttributes minusSet:attributesStillInCluster];
3116-
MTRClusterPath * clusterPathToRemoveAttributesFrom;
3117-
for (MTRClusterPath * path in _persistedClusters) {
3118-
if ([path.endpoint isEqualToNumber:attributePath.endpoint] && [path.cluster isEqualToNumber:attributePath.cluster]) {
3119-
clusterPathToRemoveAttributesFrom = path;
3120-
break;
3121-
}
3122-
}
3123-
[self _removeAttributes:[toBeRemovedAttributes copy] fromCluster:clusterPathToRemoveAttributesFrom];
3124-
[self.deviceController.controllerDataStore removeAttributes:[toBeRemovedAttributes copy] fromCluster:clusterPathToRemoveAttributesFrom forNodeID:self.nodeID];
3125+
[self _removeAttributes:toBeRemovedAttributes fromCluster:clusterPath];
31253126
}
31263127

3127-
- (void)_pruneOrphanedEndpointsAndClusters:(MTRAttributePath *)attributePath
3128-
previousValue:(NSDictionary *)previousValue
3129-
attributeDataValue:(NSDictionary *)attributeDataValue
3128+
- (void)_pruneStoredDataForPath:(MTRAttributePath *)attributePath
3129+
missingFrom:(MTRDeviceDataValueDictionary)newAttributeDataValue
31303130
{
31313131
os_unfair_lock_assert_owner(&self->_lock);
31323132

3133-
NSNumber * rootEndpoint = @0;
3134-
3135-
if (_persistedClusters == nil || _persistedClusterData == nil || !previousValue.count) {
3133+
if (![self _dataStoreExists] && !_clusterDataToPersist.count) {
3134+
MTR_LOG_DEBUG("%@ No data store to prune from", self);
31363135
return;
31373136
}
3137+
31383138
// Check if parts list changed or server list changed for the descriptor cluster or the attribute list changed for a cluster.
31393139
// If yes, we might need to prune any deleted endpoints, clusters or attributes from the storage and persisted cluster data.
31403140
if (attributePath.cluster.unsignedLongValue == MTRClusterIDTypeDescriptorID) {
3141-
if (attributePath.attribute.unsignedLongValue == MTRAttributeIDTypeClusterDescriptorAttributePartsListID && [attributePath.endpoint isEqualToNumber:rootEndpoint]) {
3142-
[self _pruneOrphanedEndpoints:previousValue newPartsListValue:attributeDataValue];
3143-
} else if (attributePath.attribute.unsignedLongValue == MTRAttributeIDTypeClusterDescriptorAttributeServerListID) {
3144-
[self _pruneOrphanedClusters:attributePath previousServerListValue:previousValue newServerListValue:attributeDataValue];
3141+
if (attributePath.attribute.unsignedLongValue == MTRAttributeIDTypeClusterDescriptorAttributePartsListID && [attributePath.endpoint isEqualToNumber:@(kRootEndpointId)]) {
3142+
[self _pruneEndpointsIn:[self _cachedAttributeValueForPath:attributePath] missingFrom:newAttributeDataValue];
3143+
return;
3144+
}
3145+
3146+
if (attributePath.attribute.unsignedLongValue == MTRAttributeIDTypeClusterDescriptorAttributeServerListID) {
3147+
[self _pruneClustersIn:[self _cachedAttributeValueForPath:attributePath] missingFrom:newAttributeDataValue forEndpoint:attributePath.endpoint];
3148+
return;
31453149
}
31463150
}
31473151

31483152
if (attributePath.attribute.unsignedLongValue == MTRAttributeIDTypeGlobalAttributeAttributeListID) {
3149-
[self _pruneOrphanedAttributes:attributePath newAttributeListValue:attributeDataValue];
3153+
[self _pruneAttributesIn:[self _cachedAttributeValueForPath:attributePath] missingFrom:newAttributeDataValue forCluster:[MTRClusterPath clusterPathWithEndpointID:attributePath.endpoint clusterID:attributePath.cluster]];
31503154
}
31513155
}
31523156

@@ -3203,7 +3207,7 @@ - (NSArray *)_getAttributesToReportWithReportedValues:(NSArray<NSDictionary<NSSt
32033207
[self _noteDataVersion:dataVersion forClusterPath:clusterPath];
32043208
}
32053209

3206-
[self _pruneOrphanedEndpointsAndClusters:attributePath previousValue:previousValue attributeDataValue:attributeDataValue];
3210+
[self _pruneStoredDataForPath:attributePath missingFrom:attributeDataValue];
32073211

32083212
if (!_deviceConfigurationChanged) {
32093213
_deviceConfigurationChanged = [self _attributeAffectsDeviceConfiguration:attributePath];

src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ typedef void (^MTRDeviceControllerDataStoreClusterDataHandler)(NSDictionary<NSNu
7676
- (nullable MTRDeviceClusterData *)getStoredClusterDataForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID;
7777
- (void)storeClusterData:(NSDictionary<MTRClusterPath *, MTRDeviceClusterData *> *)clusterData forNodeID:(NSNumber *)nodeID;
7878
- (void)clearStoredClusterDataForNodeID:(NSNumber *)nodeID;
79+
- (void)clearStoredClusterDataForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID;
7980
- (void)clearStoredClusterDataForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID;
80-
- (void)removeEndpointFromEndpointIndex:(NSNumber *)endpointID forNodeID:(NSNumber *)nodeID;
8181
- (void)removeAttributes:(NSSet<NSNumber *> *)attributes fromCluster:(MTRClusterPath *)path forNodeID:(NSNumber *)nodeID;
8282
- (void)clearAllStoredClusterData;
8383

src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm

+52-22
Original file line numberDiff line numberDiff line change
@@ -446,24 +446,21 @@ - (BOOL)_storeEndpointIndex:(NSArray<NSNumber *> *)endpointIndex forNodeID:(NSNu
446446
return [self _storeAttributeCacheValue:endpointIndex forKey:[self _endpointIndexKeyForNodeID:nodeID]];
447447
}
448448

449-
- (void)removeEndpointFromEndpointIndex:(NSNumber *)endpointID forNodeID:(NSNumber *)nodeID
449+
- (BOOL)_removeEndpointFromEndpointIndex:(NSNumber *)endpointID forNodeID:(NSNumber *)nodeID
450450
{
451+
dispatch_assert_queue(_storageDelegateQueue);
451452
if (!endpointID || !nodeID) {
452453
MTR_LOG_ERROR("%s: unexpected nil input", __func__);
453-
return;
454+
return NO;
454455
}
455-
dispatch_async(_storageDelegateQueue, ^{
456-
NSMutableArray * endpointIndex = [[self _fetchEndpointIndexForNodeID:nodeID] mutableCopy];
457-
if (endpointIndex == nil) {
458-
return;
459-
}
460456

461-
[endpointIndex removeObject:endpointID];
462-
BOOL success = [self _storeEndpointIndex:endpointIndex forNodeID:nodeID];
463-
if (!success) {
464-
MTR_LOG_ERROR("removeEndpointFromEndpointIndex: _storeEndpointIndex for node 0x%016llX", nodeID.unsignedLongLongValue);
465-
}
466-
});
457+
NSMutableArray<NSNumber *> * endpointIndex = [[self _fetchEndpointIndexForNodeID:nodeID] mutableCopy];
458+
if (endpointIndex == nil) {
459+
return NO;
460+
}
461+
462+
[endpointIndex removeObject:endpointID];
463+
return [self _storeEndpointIndex:endpointIndex forNodeID:nodeID];
467464
}
468465

469466
- (BOOL)_deleteEndpointIndexForNodeID:(NSNumber *)nodeID
@@ -517,6 +514,7 @@ - (BOOL)_deleteClusterIndexForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)e
517514
MTR_LOG_ERROR("%s: unexpected nil input", __func__);
518515
return NO;
519516
}
517+
520518
return [self _removeAttributeCacheValueForKey:[self _clusterIndexKeyForNodeID:nodeID endpointID:endpointID]];
521519
}
522520

@@ -718,25 +716,54 @@ - (void)clearStoredClusterDataForNodeID:(NSNumber *)nodeID
718716
});
719717
}
720718

721-
- (void)clearStoredClusterDataForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID
719+
- (void)clearStoredClusterDataForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID
722720
{
723721
dispatch_async(_storageDelegateQueue, ^{
724-
BOOL success = [self _deleteClusterDataForNodeID:nodeID endpointID:endpointID clusterID:clusterID];
722+
BOOL success = [self _removeEndpointFromEndpointIndex:endpointID forNodeID:nodeID];
725723
if (!success) {
726-
MTR_LOG_ERROR("clearStoredClusterDataForNodeID: _deleteClusterDataForNodeID failed for node 0x%016llX endpoint %u cluster 0x%08lX", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue, clusterID.unsignedLongValue);
727-
return;
724+
MTR_LOG_ERROR("removeEndpointFromEndpointIndex for endpointID %u failed for node 0x%016llX", endpointID.unsignedShortValue, nodeID.unsignedLongLongValue);
725+
}
726+
727+
NSArray<NSNumber *> * clusterIndex = [self _fetchClusterIndexForNodeID:nodeID endpointID:endpointID];
728+
729+
for (NSNumber * cluster in clusterIndex)
730+
{
731+
success = [self _deleteClusterDataForNodeID:nodeID endpointID:endpointID clusterID:cluster];
732+
if (!success) {
733+
MTR_LOG_ERROR("Delete failed for clusterData for node 0x%016llX endpoint %u cluster 0x%08lX", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue, cluster.unsignedLongValue);
734+
}
735+
}
736+
737+
success = [self _deleteClusterIndexForNodeID:nodeID endpointID:endpointID];
738+
if (!success) {
739+
MTR_LOG_ERROR("Delete failed for clusterIndex for node 0x%016llX endpoint %u", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue);
728740
}
729741

742+
MTR_LOG("clearStoredClusterDataForNodeID: Deleted endpoint %u for node 0x%016llX successfully", endpointID.unsignedShortValue, nodeID.unsignedLongLongValue);
743+
});
744+
}
745+
746+
- (void)clearStoredClusterDataForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID
747+
{
748+
dispatch_async(_storageDelegateQueue, ^{
730749
NSArray<NSNumber *> * clusterIndex = [self _fetchClusterIndexForNodeID:nodeID endpointID:endpointID];
731750
NSMutableArray<NSNumber *> * clusterIndexCopy = [clusterIndex mutableCopy];
732751
[clusterIndexCopy removeObject:clusterID];
733752

753+
BOOL success;
734754
if (clusterIndexCopy.count != clusterIndex.count) {
735755
success = [self _storeClusterIndex:clusterIndexCopy forNodeID:nodeID endpointID:endpointID];
736756
if (!success) {
737757
MTR_LOG_ERROR("clearStoredClusterDataForNodeID: _storeClusterIndex failed for node 0x%016llX endpoint %u", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue);
738758
}
739759
}
760+
761+
success = [self _deleteClusterDataForNodeID:nodeID endpointID:endpointID clusterID:clusterID];
762+
if (!success) {
763+
MTR_LOG_ERROR("clearStoredClusterDataForNodeID: _deleteClusterDataForNodeID failed for node 0x%016llX endpoint %u cluster 0x%08lX", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue, clusterID.unsignedLongValue);
764+
return;
765+
}
766+
740767
MTR_LOG("clearStoredClusterDataForNodeID: Deleted endpoint %u cluster 0x%08lX for node 0x%016llX successfully", endpointID.unsignedShortValue, clusterID.unsignedLongValue, nodeID.unsignedLongLongValue);
741768
});
742769
}
@@ -750,11 +777,14 @@ - (void)removeAttributes:(NSSet<NSNumber *> *)attributes fromCluster:(MTRCluster
750777
for (NSNumber * attribute in attributes) {
751778
[clusterData removeValueForAttribute:attribute];
752779
}
753-
BOOL success = [self _storeClusterData:clusterData forNodeID:nodeID endpointID:path.endpoint clusterID:path.cluster];
754-
if (!success) {
755-
MTR_LOG_ERROR("removeAttributes: _storeClusterData failed for node 0x%016llX endpoint %u", nodeID.unsignedLongLongValue, path.endpoint.unsignedShortValue);
756-
}
757-
MTR_LOG("removeAttributes: Deleted attributes %@ from endpoint %u cluster 0x%08lX for node 0x%016llX successfully", attributes, path.endpoint.unsignedShortValue, path.cluster.unsignedLongValue, nodeID.unsignedLongLongValue);
780+
781+
dispatch_async(_storageDelegateQueue, ^{
782+
BOOL success = [self _storeClusterData:clusterData forNodeID:nodeID endpointID:path.endpoint clusterID:path.cluster];
783+
if (!success) {
784+
MTR_LOG_ERROR("removeAttributes: _storeClusterData failed for node 0x%016llX endpoint %u", nodeID.unsignedLongLongValue, path.endpoint.unsignedShortValue);
785+
}
786+
MTR_LOG("removeAttributes: Deleted attributes %@ from endpoint %u cluster 0x%08lX for node 0x%016llX successfully", attributes, path.endpoint.unsignedShortValue, path.cluster.unsignedLongValue, nodeID.unsignedLongLongValue);
787+
});
758788
}
759789

760790
- (void)clearAllStoredClusterData

0 commit comments

Comments
 (0)