diff options
| author | Hazelnoot <acomputerdog@gmail.com> | 2025-05-25 12:34:09 -0400 |
|---|---|---|
| committer | Hazelnoot <acomputerdog@gmail.com> | 2025-05-28 21:31:40 -0400 |
| commit | 35dfde838be2dd50ee37d420f87a0cac917e621c (patch) | |
| tree | d637d0c156384d2021c8d207c8b765dcc847df70 /packages/backend/src | |
| parent | minor optimization to diff-arrays (diff) | |
| download | sharkey-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.ts | 18 | ||||
| -rw-r--r-- | packages/backend/src/misc/diff-arrays.ts | 44 |
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; +} |