@@ -53,9 +53,20 @@ public final class ClientQuotasImage {
53
53
public static final ClientQuotasImage EMPTY = new ClientQuotasImage (Collections .emptyMap ());
54
54
55
55
private final Map <ClientQuotaEntity , ClientQuotaImage > entities ;
56
+ private final Map <String , Map <String , Set <Entry <ClientQuotaEntity , ClientQuotaImage >>>> entitiesByType ;
56
57
57
58
public ClientQuotasImage (Map <ClientQuotaEntity , ClientQuotaImage > entities ) {
58
59
this .entities = Collections .unmodifiableMap (entities );
60
+ Map <String , Map <String , Set <Entry <ClientQuotaEntity , ClientQuotaImage >>>> entitiesByType = new HashMap <>();
61
+ for (Entry <ClientQuotaEntity , ClientQuotaImage > entry : entities .entrySet ()) {
62
+ ClientQuotaEntity entity = entry .getKey ();
63
+ for (Entry <String , String > entityEntry : entity .entries ().entrySet ()) {
64
+ entitiesByType .putIfAbsent (entityEntry .getKey (), new HashMap <>());
65
+ entitiesByType .get (entityEntry .getKey ()).putIfAbsent (entityEntry .getValue (), new HashSet <>());
66
+ entitiesByType .get (entityEntry .getKey ()).get (entityEntry .getValue ()).add (entry );
67
+ }
68
+ }
69
+ this .entitiesByType = Collections .unmodifiableMap (entitiesByType );
59
70
}
60
71
61
72
public boolean isEmpty () {
@@ -126,40 +137,45 @@ public DescribeClientQuotasResponseData describe(DescribeClientQuotasRequestData
126
137
"user or clientId filter component." );
127
138
}
128
139
}
129
- // TODO: this is O(N). We should add indexing here to speed it up. See KAFKA-13022.
130
- for (Entry <ClientQuotaEntity , ClientQuotaImage > entry : entities .entrySet ()) {
131
- ClientQuotaEntity entity = entry .getKey ();
132
- ClientQuotaImage quotaImage = entry .getValue ();
133
- if (matches (entity , exactMatch , typeMatch , request .strict ())) {
134
- response .entries ().add (toDescribeEntry (entity , quotaImage ));
135
- }
136
- }
137
- return response ;
138
- }
139
140
140
- private static boolean matches (ClientQuotaEntity entity ,
141
- Map <String , String > exactMatch ,
142
- Set <String > typeMatch ,
143
- boolean strict ) {
144
- if (strict ) {
145
- if (entity .entries ().size () != exactMatch .size () + typeMatch .size ()) {
146
- return false ;
141
+ Set <ClientQuotaEntity > addedEntities = new HashSet <>();
142
+ for (Entry <String , String > exactMatchEntry : exactMatch .entrySet ()) {
143
+ if (entitiesByType .containsKey (exactMatchEntry .getKey ()) &&
144
+ entitiesByType .get (exactMatchEntry .getKey ()).containsKey (exactMatchEntry .getValue ())) {
145
+ for (Entry <ClientQuotaEntity , ClientQuotaImage > entry : entitiesByType .get (exactMatchEntry .getKey ()).get (exactMatchEntry .getValue ())) {
146
+ if (request .strict () && !entry .getKey ().entries ().equals (exactMatch )) {
147
+ continue ;
148
+ }
149
+ if (!addedEntities .contains (entry .getKey ())) {
150
+ addedEntities .add (entry .getKey ());
151
+ response .entries ().add (toDescribeEntry (entry .getKey (), entry .getValue ()));
152
+ }
153
+ }
147
154
}
148
155
}
149
- for (Entry <String , String > entry : exactMatch .entrySet ()) {
150
- if (!entity .entries ().containsKey (entry .getKey ())) {
151
- return false ;
152
- }
153
- if (!Objects .equals (entity .entries ().get (entry .getKey ()), entry .getValue ())) {
154
- return false ;
156
+
157
+ for (String type : typeMatch ) {
158
+ if (entitiesByType .containsKey (type )) {
159
+ for (Set <Entry <ClientQuotaEntity , ClientQuotaImage >> entrySet : entitiesByType .get (type ).values ()) {
160
+ for (Entry <ClientQuotaEntity , ClientQuotaImage > entry : entrySet ) {
161
+ if (request .strict () && entry .getKey ().entries ().size () != typeMatch .size ()) {
162
+ continue ;
163
+ }
164
+ if (!addedEntities .contains (entry .getKey ())) {
165
+ addedEntities .add (entry .getKey ());
166
+ response .entries ().add (toDescribeEntry (entry .getKey (), entry .getValue ()));
167
+ }
168
+ }
169
+ }
155
170
}
156
171
}
157
- for (String type : typeMatch ) {
158
- if (!entity .entries ().containsKey (type )) {
159
- return false ;
172
+
173
+ if (!request .strict () && exactMatch .isEmpty () && typeMatch .isEmpty ()) {
174
+ for (Entry <ClientQuotaEntity , ClientQuotaImage > entry : entities .entrySet ()) {
175
+ response .entries ().add (toDescribeEntry (entry .getKey (), entry .getValue ()));
160
176
}
161
177
}
162
- return true ;
178
+ return response ;
163
179
}
164
180
165
181
private static EntryData toDescribeEntry (ClientQuotaEntity entity ,
0 commit comments