Skip to content

Commit db8ef62

Browse files
committed
invalidate the decodedEntitiesEntry instead of the query directly
1 parent 8417d3b commit db8ef62

File tree

4 files changed

+44
-43
lines changed

4 files changed

+44
-43
lines changed

packages/hypergraph/src/entity/decodedEntitiesCache.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export type DecodedEntitiesCacheEntry = {
1414
string, // instead of serializedQueryKey as string we could also have the actual params
1515
QueryEntry
1616
>;
17+
isInvalidated: boolean;
1718
};
1819

1920
/*
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import type { DecodedEntitiesCacheEntry } from './decodedEntitiesCache.js';
2+
3+
export const entityRelationParentsMap: Map<
4+
string, // entity ID
5+
Array<DecodedEntitiesCacheEntry>
6+
> = new Map();

packages/hypergraph/src/entity/findMany.ts

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import type { DocHandle, Patch } from '@automerge/automerge-repo';
22
import * as Schema from 'effect/Schema';
3-
import { type QueryEntry, decodedEntitiesCache } from './decodedEntitiesCache.js';
3+
import { type DecodedEntitiesCacheEntry, type QueryEntry, decodedEntitiesCache } from './decodedEntitiesCache.js';
4+
import { entityRelationParentsMap } from './entityRelationParentsMap.js';
45
import { getEntityRelations } from './getEntityRelations.js';
56
import { hasValidTypesProperty } from './hasValidTypesProperty.js';
67
import { isReferenceField } from './isReferenceField.js';
7-
import { relationParentQueries } from './relationParentQueries.js';
88
import type { AnyNoContext, DocumentContent, Entity } from './types.js';
99

1010
const documentChangeListener: {
@@ -44,7 +44,7 @@ const subscribeToDocumentChanges = (handle: DocHandle<DocumentContent>) => {
4444
// reference to reduce the amount of O(n) operations per query to 1
4545
const touchedQueries = new Set<Array<string>>();
4646

47-
const touchedRelationParentQueries = new Set<QueryEntry>();
47+
const touchedRelationParents = new Set<DecodedEntitiesCacheEntry>();
4848

4949
// loop over all changed entities and update the cache
5050
for (const entityId of changedEntities) {
@@ -77,27 +77,27 @@ const subscribeToDocumentChanges = (handle: DocHandle<DocumentContent>) => {
7777
for (const [key, value] of Object.entries(decoded)) {
7878
if (Array.isArray(value)) {
7979
for (const relationEntity of value) {
80-
let relationParentQueriesEntry = relationParentQueries.get(relationEntity.id);
81-
if (!relationParentQueriesEntry) {
82-
relationParentQueriesEntry = [];
83-
relationParentQueries.set(relationEntity.id, relationParentQueriesEntry);
80+
let relationParentEntry = entityRelationParentsMap.get(relationEntity.id);
81+
if (!relationParentEntry) {
82+
relationParentEntry = [];
83+
entityRelationParentsMap.set(relationEntity.id, relationParentEntry);
8484
}
8585

86-
relationParentQueriesEntry.push(query);
86+
relationParentEntry.push(cacheEntry);
8787
}
8888
}
8989
}
9090
}
9191

9292
entityTypes.add(typeName);
9393

94-
// gather all the queries of impacted parent relation queries
95-
if (relationParentQueries.has(entityId)) {
96-
const queries = relationParentQueries.get(entityId);
97-
if (!queries) return;
94+
// gather all the decodedEntitiesCacheEntries
95+
if (entityRelationParentsMap.has(entityId)) {
96+
const decodedEntitiesCacheEntries = entityRelationParentsMap.get(entityId);
97+
if (!decodedEntitiesCacheEntries) return;
9898

99-
for (const query of queries) {
100-
touchedRelationParentQueries.add(query);
99+
for (const entry of decodedEntitiesCacheEntries) {
100+
touchedRelationParents.add(entry);
101101
}
102102
}
103103
}
@@ -122,12 +122,12 @@ const subscribeToDocumentChanges = (handle: DocHandle<DocumentContent>) => {
122122
}
123123

124124
// gather all the queries of impacted parent relation queries
125-
if (relationParentQueries.has(entityId)) {
126-
const queries = relationParentQueries.get(entityId);
127-
if (!queries) return;
125+
if (entityRelationParentsMap.has(entityId)) {
126+
const decodedEntitiesCacheEntries = entityRelationParentsMap.get(entityId);
127+
if (!decodedEntitiesCacheEntries) return;
128128

129-
for (const query of queries) {
130-
touchedRelationParentQueries.add(query);
129+
for (const entry of decodedEntitiesCacheEntries) {
130+
touchedRelationParents.add(entry);
131131
}
132132
}
133133
}
@@ -156,10 +156,13 @@ const subscribeToDocumentChanges = (handle: DocHandle<DocumentContent>) => {
156156

157157
// trigger all the listeners of the parent relation queries
158158
// TODO: align with the touchedQueries to avoid unnecessary trigger calls
159-
for (const query of touchedRelationParentQueries) {
160-
query.isInvalidated = true;
161-
for (const listener of query.listeners) {
162-
listener();
159+
for (const decodedEntitiesCacheEntry of touchedRelationParents) {
160+
decodedEntitiesCacheEntry.isInvalidated = true;
161+
for (const query of decodedEntitiesCacheEntry.queries.values()) {
162+
query.isInvalidated = true;
163+
for (const listener of query.listeners) {
164+
listener();
165+
}
163166
}
164167
}
165168
};
@@ -218,10 +221,11 @@ export function subscribeToFindMany<const S extends AnyNoContext>(
218221

219222
const getEntities = () => {
220223
const cacheEntry = decodedEntitiesCache.get(typeName);
221-
const query = cacheEntry?.queries.get(queryKey);
224+
if (!cacheEntry) return stableEmptyArray;
225+
const query = cacheEntry.queries.get(queryKey);
222226
if (!query) return stableEmptyArray;
223227

224-
if (!query.isInvalidated) {
228+
if (!cacheEntry.isInvalidated && !query.isInvalidated) {
225229
return query.data;
226230
}
227231

@@ -239,17 +243,18 @@ export function subscribeToFindMany<const S extends AnyNoContext>(
239243
}
240244
}
241245

246+
cacheEntry.isInvalidated = false;
242247
query.isInvalidated = false;
243248
return query.data;
244249
};
245250

246251
if (!decodedEntitiesCache.has(typeName)) {
247252
const entities = findMany(handle, type);
248253
const entitiesMap = new Map();
249-
const relationParentQueries = new Map();
254+
const relationParent = new Map();
250255
for (const entity of entities) {
251256
entitiesMap.set(entity.id, entity);
252-
relationParentQueries.set(entity.id, new Map());
257+
relationParent.set(entity.id, new Map());
253258
}
254259

255260
const queries = new Map<string, QueryEntry>();
@@ -265,6 +270,7 @@ export function subscribeToFindMany<const S extends AnyNoContext>(
265270
type,
266271
entities: entitiesMap,
267272
queries,
273+
isInvalidated: false,
268274
});
269275
}
270276

@@ -281,26 +287,20 @@ export function subscribeToFindMany<const S extends AnyNoContext>(
281287
const typeName = type.name;
282288
const entities = findMany(handle, type);
283289

284-
if (decodedEntitiesCache.has(typeName)) {
285-
// add a listener to the existing query
286-
const cacheEntry = decodedEntitiesCache.get(typeName);
287-
288-
for (const entity of entities) {
289-
cacheEntry?.entities.set(entity.id, entity);
290-
}
291-
} else {
290+
if (!decodedEntitiesCache.has(typeName)) {
292291
const entitiesMap = new Map();
293-
const relationParentQueries = new Map();
292+
const relationParent = new Map();
294293
for (const entity of entities) {
295294
entitiesMap.set(entity.id, entity);
296-
relationParentQueries.set(entity.id, new Map());
295+
relationParent.set(entity.id, new Map());
297296
}
298297

299298
decodedEntitiesCache.set(typeName, {
300299
decoder: decode,
301300
type,
302301
entities: entitiesMap,
303302
queries: new Map(),
303+
isInvalidated: false,
304304
});
305305
}
306306
}

packages/hypergraph/src/entity/relationParentQueries.ts

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)