46 lines
1.6 KiB
Diff
46 lines
1.6 KiB
Diff
# UNDF: UNDF-2026-000000260
|
|
--- a/src/acl.c
|
|
+++ b/src/acl.c
|
|
@@ -1913,6 +1913,8 @@ list *getUpcomingChannelList(user *new, user *original) {
|
|
list *getUpcomingChannelList(user *new, user *original) {
|
|
listIter li, lpi;
|
|
listNode *ln, *lpn;
|
|
+ dict *upcoming_set; /* O(1) exact-match lookup; avoids O(U) listSearchKey per channel */
|
|
+ dictEntry *de;
|
|
|
|
/* Optimization: we check if any selector has all channel permissions. */
|
|
listRewind(new->selectors,&li);
|
|
@@ -1929,8 +1931,11 @@ list *getUpcomingChannelList(user *new, user *original) {
|
|
* against it. */
|
|
list *upcoming = listCreate();
|
|
+ upcoming_set = dictCreate(&sdsReplyDictType);
|
|
listRewind(new->selectors,&li);
|
|
while((ln = listNext(&li))) {
|
|
aclSelector *s = (aclSelector *) listNodeValue(ln);
|
|
listRewind(s->channels, &lpi);
|
|
while((lpn = listNext(&lpi))) {
|
|
listAddNodeTail(upcoming, listNodeValue(lpn));
|
|
+ dictAdd(upcoming_set, listNodeValue(lpn), NULL); /* O(1) insert */
|
|
}
|
|
}
|
|
|
|
@@ -1950,7 +1955,7 @@ list *getUpcomingChannelList(user *new, user *original) {
|
|
listRewind(s->channels, &lpi);
|
|
while((lpn = listNext(&lpi)) && match) {
|
|
- if (!listSearchKey(upcoming, listNodeValue(lpn))) { /* was O(U) */
|
|
+ if (dictFind(upcoming_set, listNodeValue(lpn)) == NULL) { /* O(1) */
|
|
match = 0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
+ dictRelease(upcoming_set);
|
|
if (match) {
|
|
/* All channels were matched, no need to kill clients. */
|
|
listRelease(upcoming);
|
|
return NULL;
|
|
}
|
|
|
|
return upcoming;
|
|
}
|