summaryrefslogtreecommitdiff
path: root/packages/backend/src
diff options
context:
space:
mode:
authorHazelnoot <acomputerdog@gmail.com>2025-05-25 12:34:09 -0400
committerHazelnoot <acomputerdog@gmail.com>2025-05-28 21:31:40 -0400
commit35dfde838be2dd50ee37d420f87a0cac917e621c (patch)
treed637d0c156384d2021c8d207c8b765dcc847df70 /packages/backend/src
parentminor optimization to diff-arrays (diff)
downloadsharkey-35dfde838be2dd50ee37d420f87a0cac917e621c.tar.gz
sharkey-35dfde838be2dd50ee37d420f87a0cac917e621c.tar.bz2
sharkey-35dfde838be2dd50ee37d420f87a0cac917e621c.zip
add function diffArraysSimple for more efficient change detection
Diffstat (limited to 'packages/backend/src')
-rw-r--r--packages/backend/src/core/FederatedInstanceService.ts18
-rw-r--r--packages/backend/src/misc/diff-arrays.ts44
2 files changed, 50 insertions, 12 deletions
diff --git a/packages/backend/src/core/FederatedInstanceService.ts b/packages/backend/src/core/FederatedInstanceService.ts
index eb634b1d68..34df10f0ff 100644
--- a/packages/backend/src/core/FederatedInstanceService.ts
+++ b/packages/backend/src/core/FederatedInstanceService.ts
@@ -14,7 +14,7 @@ import { UtilityService } from '@/core/UtilityService.js';
import { bindThis } from '@/decorators.js';
import type { GlobalEvents } from '@/core/GlobalEventService.js';
import { Serialized } from '@/types.js';
-import { diffArrays } from '@/misc/diff-arrays.js';
+import { diffArrays, diffArraysSimple } from '@/misc/diff-arrays.js';
@Injectable()
export class FederatedInstanceService implements OnApplicationShutdown {
@@ -99,11 +99,11 @@ export class FederatedInstanceService implements OnApplicationShutdown {
private syncCache(before: Serialized<MiMeta | undefined>, after: Serialized<MiMeta>): void {
const changed =
- hasDiff(before?.blockedHosts, after.blockedHosts) ||
- hasDiff(before?.silencedHosts, after.silencedHosts) ||
- hasDiff(before?.mediaSilencedHosts, after.mediaSilencedHosts) ||
- hasDiff(before?.federationHosts, after.federationHosts) ||
- hasDiff(before?.bubbleInstances, after.bubbleInstances);
+ diffArraysSimple(before?.blockedHosts, after.blockedHosts) ||
+ diffArraysSimple(before?.silencedHosts, after.silencedHosts) ||
+ diffArraysSimple(before?.mediaSilencedHosts, after.mediaSilencedHosts) ||
+ diffArraysSimple(before?.federationHosts, after.federationHosts) ||
+ diffArraysSimple(before?.bubbleInstances, after.bubbleInstances);
if (changed) {
// We have to clear the whole thing, otherwise subdomains won't be synced.
@@ -134,9 +134,3 @@ export class FederatedInstanceService implements OnApplicationShutdown {
this.dispose();
}
}
-
-function hasDiff(before: string[] | null | undefined, after: string[] | null | undefined): boolean {
- const { added, removed } = diffArrays(before, after);
- return added.length > 0 || removed.length > 0;
-}
-
diff --git a/packages/backend/src/misc/diff-arrays.ts b/packages/backend/src/misc/diff-arrays.ts
index b3879cc996..b50ca1d4f7 100644
--- a/packages/backend/src/misc/diff-arrays.ts
+++ b/packages/backend/src/misc/diff-arrays.ts
@@ -56,3 +56,47 @@ export function diffArrays<T>(dataBefore: T[] | null | undefined, dataAfter: T[]
// data NEITHER before nor after => no change
return { added: [], removed: [] };
}
+
+/**
+ * Checks for any difference between two snapshots of data.
+ * Null, undefined, and empty arrays are supported, and duplicate values are ignored.
+ * The inputs are treated as un-ordered, so a re-ordering of the same data will NOT be considered a change.
+ * @param dataBefore Array containing data before the change
+ * @param dataAfter Array containing data after the change
+ */
+export function diffArraysSimple<T>(dataBefore: T[] | null | undefined, dataAfter: T[] | null | undefined): boolean {
+ const before = dataBefore ? new Set(dataBefore) : null;
+ const after = dataAfter ? new Set(dataAfter) : null;
+
+ if (before?.size && after?.size) {
+ // different size => changed
+ if (before.size !== after.size) return true;
+
+ // removed => changed
+ for (const host of before) {
+ // delete operation removes duplicates to speed up the "after" loop
+ if (!after.delete(host)) {
+ return true;
+ }
+ }
+
+ // added => changed
+ for (const host of after) {
+ if (!before.has(host)) {
+ return true;
+ }
+ }
+
+ // identical values => no change
+ return false;
+ }
+
+ // before and NOT after => change
+ if (before?.size) return true;
+
+ // after and NOT before => change
+ if (after?.size) return true;
+
+ // NEITHER before nor after => no change
+ return false;
+}