26
26
namespace chip {
27
27
namespace app {
28
28
29
- void ServerClusterInterfaceRegistry::ClearSingleLinkedList (RegisteredServerClusterInterface * clusters)
30
- {
31
- while (clusters != nullptr )
32
- {
33
- RegisteredServerClusterInterface * next = clusters->next ;
34
- Platform::Delete (clusters);
35
- clusters = next;
36
- }
37
- }
38
-
39
29
ServerClusterInterfaceRegistry::~ServerClusterInterfaceRegistry ()
40
30
{
41
- while (mEndpoints != nullptr )
31
+ while (mRegistrations != nullptr )
42
32
{
43
- UnregisterAllFromEndpoint (mEndpoints ->endpointId );
33
+ ServerClusterRegistration * next = mRegistrations ->next ;
34
+ mRegistrations ->next = nullptr ;
35
+ mRegistrations = next;
44
36
}
45
37
}
46
38
47
- CHIP_ERROR ServerClusterInterfaceRegistry::AllocateNewEndpointClusters (EndpointId endpointId, EndpointClusters *& dest )
39
+ CHIP_ERROR ServerClusterInterfaceRegistry::Register (ServerClusterRegistration & entry )
48
40
{
49
- auto result = Platform::New<EndpointClusters>();
50
- VerifyOrReturnError (result != nullptr , CHIP_ERROR_NO_MEMORY);
41
+ // we have no strong way to check if entry is already registered somewhere else, so we use "next" as some
42
+ // form of double-check
43
+ VerifyOrReturnError (entry.next == nullptr , CHIP_ERROR_INVALID_ARGUMENT);
44
+ VerifyOrReturnError (entry.serverClusterInterface != nullptr , CHIP_ERROR_INVALID_ARGUMENT);
51
45
52
- result->endpointId = endpointId;
53
- result->firstCluster = nullptr ;
54
- result->next = mEndpoints ;
55
- mEndpoints = result;
56
- dest = result;
46
+ ConcreteClusterPath path = entry.serverClusterInterface ->GetPath ();
57
47
58
- return CHIP_NO_ERROR;
59
- }
60
-
61
- CHIP_ERROR ServerClusterInterfaceRegistry::Register (EndpointId endpointId, ServerClusterInterface * cluster)
62
- {
63
- VerifyOrReturnError (cluster != nullptr , CHIP_ERROR_INVALID_ARGUMENT);
64
- VerifyOrReturnError (endpointId != kInvalidEndpointId , CHIP_ERROR_INVALID_ARGUMENT);
65
- VerifyOrReturnError (cluster->GetClusterId () != kInvalidClusterId , CHIP_ERROR_INVALID_ARGUMENT);
48
+ VerifyOrReturnError (path.HasValidIds (), CHIP_ERROR_INVALID_ARGUMENT);
66
49
67
- // duplicate registrations are disallowed
68
- VerifyOrReturnError (Get (ConcreteClusterPath (endpointId, cluster->GetClusterId ())) == nullptr , CHIP_ERROR_DUPLICATE_KEY_ID);
50
+ // Double-checking for duplicates makes the checks O(n^2) on the total number of registered
51
+ // items. We preserve this however we may want to make this optional at some point in time.
52
+ VerifyOrReturnError (Get (path) == nullptr , CHIP_ERROR_DUPLICATE_KEY_ID);
69
53
70
- EndpointClusters * endpointClusters = FindClusters (endpointId);
71
- if (endpointClusters == nullptr )
72
- {
73
- ReturnErrorOnFailure (AllocateNewEndpointClusters (endpointId, endpointClusters));
74
- }
75
-
76
- auto entry = Platform::New<RegisteredServerClusterInterface>(cluster, endpointClusters->firstCluster );
77
-
78
- // If this fails, we still have the `AllocateNewEndpointClusters` succeeding,
79
- // so an empty list for this cluster exists. No cleanup for now (smaller code)
80
- // as an empty list will probably not cause problems (this is the same as all
81
- // clusters on an endpoint getting unregistered - we do not clean mEndpoints except
82
- // in UnregisterAllFromEndpoint)
83
- VerifyOrReturnError (entry != nullptr , CHIP_ERROR_NO_MEMORY);
84
-
85
- endpointClusters->firstCluster = entry;
54
+ entry.next = mRegistrations ;
55
+ mRegistrations = &entry;
86
56
87
57
return CHIP_NO_ERROR;
88
58
}
89
59
90
60
ServerClusterInterface * ServerClusterInterfaceRegistry::Unregister (const ConcreteClusterPath & path)
91
61
{
92
- EndpointClusters * endpointClusters = FindClusters (path.mEndpointId );
93
- VerifyOrReturnValue (endpointClusters != nullptr , nullptr );
94
- VerifyOrReturnValue (endpointClusters->firstCluster != nullptr , nullptr );
95
-
96
- RegisteredServerClusterInterface * prev = nullptr ;
97
- RegisteredServerClusterInterface * current = endpointClusters->firstCluster ;
62
+ ServerClusterRegistration * prev = nullptr ;
63
+ ServerClusterRegistration * current = mRegistrations ;
98
64
99
65
while (current != nullptr )
100
66
{
101
- if (current->serverClusterInterface ->GetClusterId () == path. mClusterId )
67
+ if (current->serverClusterInterface ->GetPath () == path)
102
68
{
103
69
// take the item out of the current list and return it.
104
- RegisteredServerClusterInterface * next = current->next ;
70
+ ServerClusterRegistration * next = current->next ;
105
71
106
72
if (prev == nullptr )
107
73
{
108
- endpointClusters-> firstCluster = next;
74
+ mRegistrations = next;
109
75
}
110
76
else
111
77
{
@@ -114,14 +80,11 @@ ServerClusterInterface * ServerClusterInterfaceRegistry::Unregister(const Concre
114
80
115
81
if (mCachedInterface == current->serverClusterInterface )
116
82
{
117
- mCachedClusterEndpointId = kInvalidEndpointId ;
118
- mCachedInterface = nullptr ;
83
+ mCachedInterface = nullptr ;
119
84
}
120
85
121
- ServerClusterInterface * result = current->serverClusterInterface ;
122
- Platform::MemoryFree (current);
123
-
124
- return result;
86
+ current->next = nullptr ; // some clearing
87
+ return current->serverClusterInterface ;
125
88
}
126
89
127
90
prev = current;
@@ -134,71 +97,57 @@ ServerClusterInterface * ServerClusterInterfaceRegistry::Unregister(const Concre
134
97
135
98
ServerClusterInterfaceRegistry::ClustersList ServerClusterInterfaceRegistry::ClustersOnEndpoint (EndpointId endpointId)
136
99
{
137
- EndpointClusters * clusters = FindClusters (endpointId);
138
-
139
- if (clusters == nullptr )
140
- {
141
- return nullptr ;
142
- }
143
-
144
- return clusters->firstCluster ;
100
+ return { mRegistrations , endpointId };
145
101
}
146
102
147
103
void ServerClusterInterfaceRegistry::UnregisterAllFromEndpoint (EndpointId endpointId)
148
104
{
149
- if (mCachedClusterEndpointId == endpointId)
150
- {
151
- // all clusters on the given endpoint will be unregistered.
152
- mCachedInterface = nullptr ;
153
- mCachedClusterEndpointId = kInvalidEndpointId ;
154
- }
155
-
156
- EndpointClusters * prev = nullptr ;
157
- EndpointClusters * current = mEndpoints ;
105
+ ServerClusterRegistration * prev = nullptr ;
106
+ ServerClusterRegistration * current = mRegistrations ;
158
107
while (current != nullptr )
159
108
{
160
- if (current->endpointId == endpointId)
109
+ if (current->serverClusterInterface -> GetPath (). mEndpointId == endpointId)
161
110
{
111
+ if (mCachedInterface == current->serverClusterInterface )
112
+ {
113
+ mCachedInterface = nullptr ;
114
+ }
162
115
if (prev == nullptr )
163
116
{
164
- mEndpoints = current->next ;
117
+ mRegistrations = current->next ;
165
118
}
166
119
else
167
120
{
168
121
prev->next = current->next ;
169
122
}
170
- ClearSingleLinkedList (current->firstCluster );
171
- Platform::Delete (current);
172
- return ;
123
+ ServerClusterRegistration * actual_next = current->next ;
124
+ current->next = nullptr ; // some clearing
125
+ current = actual_next;
126
+ }
127
+ else
128
+ {
129
+ prev = current;
130
+ current = current->next ;
173
131
}
174
-
175
- prev = current;
176
- current = current->next ;
177
132
}
178
133
}
179
134
180
135
ServerClusterInterface * ServerClusterInterfaceRegistry::Get (const ConcreteClusterPath & path)
181
136
{
182
- EndpointClusters * endpointClusters = FindClusters (path.mEndpointId );
183
- VerifyOrReturnValue (endpointClusters != nullptr , nullptr );
184
- VerifyOrReturnValue (endpointClusters->firstCluster != nullptr , nullptr );
185
-
186
137
// Check the cache to speed things up
187
- if ((mCachedClusterEndpointId == path.mEndpointId ) && (mCachedInterface != nullptr ) &&
188
- (mCachedInterface ->GetClusterId () == path.mClusterId ))
138
+ if ((mCachedInterface != nullptr ) && (mCachedInterface ->GetPath () == path))
189
139
{
190
140
return mCachedInterface ;
191
141
}
192
142
193
143
// The cluster searched for is not cached, do a linear search for it
194
- RegisteredServerClusterInterface * current = endpointClusters-> firstCluster ;
144
+ ServerClusterRegistration * current = mRegistrations ;
195
145
196
146
while (current != nullptr )
197
147
{
198
- if (current->serverClusterInterface ->GetClusterId () == path. mClusterId )
148
+ if (current->serverClusterInterface ->GetPath () == path)
199
149
{
200
- mCachedClusterEndpointId = path.mEndpointId ;
201
- mCachedInterface = current->serverClusterInterface ;
150
+ mCachedInterface = current->serverClusterInterface ;
202
151
return mCachedInterface ;
203
152
}
204
153
@@ -209,18 +158,5 @@ ServerClusterInterface * ServerClusterInterfaceRegistry::Get(const ConcreteClust
209
158
return nullptr ;
210
159
}
211
160
212
- ServerClusterInterfaceRegistry::EndpointClusters * ServerClusterInterfaceRegistry::FindClusters (EndpointId endpointId)
213
- {
214
- for (EndpointClusters * p = mEndpoints ; p != nullptr ; p = p->next )
215
- {
216
- if (p->endpointId == endpointId)
217
- {
218
- return p;
219
- }
220
- }
221
-
222
- return nullptr ;
223
- }
224
-
225
161
} // namespace app
226
162
} // namespace chip
0 commit comments