Skip to content

Commit

Permalink
feat(react-components): make fetching view for all mapped nodes optio…
Browse files Browse the repository at this point in the history
…nal (#3686)

* Make view fetching optional

* Lint fixes

* Small refactor

* Removed default value and small optimisation
  • Loading branch information
Savokr authored Sep 12, 2023
1 parent 96bc82b commit bdd5bdd
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 31 deletions.
55 changes: 42 additions & 13 deletions react-components/src/components/NodeCacheProvider/FdmNodeCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export class FdmNodeCache {

const fdmKeySet = new Set(uniqueIds.map((id) => createFdmKey(id.space, id.externalId)));

const revisionToEdgesMap = await this.getAndCacheRevisionToEdgesMap(modelRevisions);
const revisionToEdgesMap = await this.getAndCacheRevisionToEdgesMap(modelRevisions, false);

const modelDataPromises = modelRevisions.map(async ({ modelId, revisionId }) => {
const revisionKey = createModelRevisionKey(modelId, revisionId);
Expand Down Expand Up @@ -160,16 +160,24 @@ export class FdmNodeCache {
}

public async getAllMappingExternalIds(
modelRevisionIds: ModelRevisionId[]
modelRevisionIds: ModelRevisionId[],
fetchViews: boolean = false
): Promise<ModelRevisionToEdgeMap> {
const [cachedRevisionIds, nonCachedRevisionIds] = partition(modelRevisionIds, (ids) => {
const key = createModelRevisionKey(ids.modelId, ids.revisionId);
return this._completeRevisions.has(key);
});

if (fetchViews) {
await this.fetchAllViewsForCachedRevisions(cachedRevisionIds);
}

const cachedEdges = cachedRevisionIds.map((id) => this.getCachedEdgesForRevision(id));

const revisionToEdgesMap = await this.getAndCacheRevisionToEdgesMap(nonCachedRevisionIds);
const revisionToEdgesMap = await this.getAndCacheRevisionToEdgesMap(
nonCachedRevisionIds,
fetchViews
);

cachedEdges.forEach(([revisionKey, edges]) => {
revisionToEdgesMap.set(revisionKey, edges);
Expand All @@ -178,12 +186,26 @@ export class FdmNodeCache {
return revisionToEdgesMap;
}

private async fetchAllViewsForCachedRevisions(
revisions: Array<{
modelId: number;
revisionId: number;
}>
): Promise<void> {
for (const revision of revisions) {
const revisionCache = this.getOrCreateRevisionCache(revision.modelId, revision.revisionId);

await revisionCache.fetchViewsForAllEdges();
}
}

private getCachedEdgesForRevision(id: {
modelId: number;
revisionId: number;
}): [ModelRevisionKey, FdmEdgeWithNode[]] {
const revisionCache = this.getOrCreateRevisionCache(id.modelId, id.revisionId);
const revisionKey = createModelRevisionKey(id.modelId, id.revisionId);

const cachedRevisionEdges = revisionCache.getAllEdges();

return [revisionKey, cachedRevisionEdges];
Expand All @@ -203,13 +225,18 @@ export class FdmNodeCache {
}

private async getAndCacheRevisionToEdgesMap(
modelRevisionIds: ModelRevisionId[]
modelRevisionIds: ModelRevisionId[],
fetchViews: boolean
): Promise<Map<ModelRevisionKey, FdmEdgeWithNode[]>> {
const revisionIds = modelRevisionIds.map((modelRevisionId) => modelRevisionId.revisionId);
const edges = await this.getEdgesForRevisions(revisionIds, this._fdmClient);
const edgesWithViews = await this.getViewsForEdges(edges);

const edgesWithOptionalViews = fetchViews
? await this.getViewsForEdges(edges)
: edges.map((edge) => ({ edge }));

const revisionToEdgesMap = await createRevisionToEdgesMap(
edgesWithViews,
edgesWithOptionalViews,
modelRevisionIds,
this._cdfClient
);
Expand All @@ -223,7 +250,7 @@ export class FdmNodeCache {
modelId: number,
revisionId: number,
treeIndex: number
): Promise<FdmEdgeWithNode[]> {
): Promise<Array<Required<FdmEdgeWithNode>>> {
const revisionCache = this.getOrCreateRevisionCache(modelId, revisionId);

return await revisionCache.getClosestParentFdmData(treeIndex);
Expand All @@ -249,6 +276,8 @@ export class FdmNodeCache {
revisionIds: number[],
fdmClient: FdmSDK
): Promise<Array<EdgeItem<InModel3dEdgeProperties>>> {
if (revisionIds.length === 0) return [];

const versionedPropertiesKey = `${SYSTEM_3D_EDGE_SOURCE.externalId}/${SYSTEM_3D_EDGE_SOURCE.version}`;
const filter = {
in: {
Expand Down Expand Up @@ -287,7 +316,7 @@ export class FdmNodeCache {
}

async function createRevisionToEdgesMap(
edgesWithViews: Array<{ edge: FdmCadEdge; view: Source }>,
edgesWithViews: Array<{ edge: FdmCadEdge; view?: Source }>,
modelRevisionIds: ModelRevisionId[],
cdfClient: CogniteClient
): Promise<Map<ModelRevisionKey, FdmEdgeWithNode[]>> {
Expand All @@ -306,9 +335,9 @@ async function createRevisionToEdgesMap(

const value = createFdmEdgeWithNode(
modelRevisionId,
modelNodeIdToNodeMap,
edgeWithView.edge,
edgeWithView.view,
modelNodeIdToNodeMap
edgeWithView.view
);

insertEdgeIntoMapList(value, map, modelRevisionId);
Expand All @@ -319,9 +348,9 @@ async function createRevisionToEdgesMap(

function createFdmEdgeWithNode(
modelRevisionId: ModelRevisionId,
modelNodeIdToNodeMap: Map<ModelNodeIdKey, Node3D>,
edge: FdmCadEdge,
view: Source,
modelNodeIdToNodeMap: Map<ModelNodeIdKey, Node3D>
view?: Source
): FdmEdgeWithNode {
const revisionNodeIdKey = createModelNodeIdKey(
modelRevisionId.modelId,
Expand Down Expand Up @@ -378,7 +407,7 @@ async function createModelNodeIdToNodeMap(
}

function createRevisionToNodeIdMap(
edgesWithViews: Array<{ edge: FdmCadEdge; view: Source }>
edgesWithViews: Array<{ edge: FdmCadEdge; view?: Source }>
): Map<RevisionId, NodeId[]> {
return edgesWithViews.reduce((revisionNodeIdMap, edgeWithView) => {
const { revisionNodeId, revisionId } = edgeWithView.edge.properties;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const useFdmNodeCache = (): FdmNodeCacheContent => {

export const useMappedEdgesForRevisions = (
modelRevisionIds: Array<{ modelId: number; revisionId: number }>,
fetchViews = false,
enabled = true
): UseQueryResult<ModelRevisionToEdgeMap> => {
const content = useFdmNodeCache();
Expand All @@ -40,9 +41,10 @@ export const useMappedEdgesForRevisions = (
[
'reveal',
'react-components',
...modelRevisionIds.map((modelRevisionId) => modelRevisionId.revisionId.toString()).sort()
...modelRevisionIds.map((modelRevisionId) => modelRevisionId.revisionId.toString()).sort(),
fetchViews
],
async () => await content.cache.getAllMappingExternalIds(modelRevisionIds),
async () => await content.cache.getAllMappingExternalIds(modelRevisionIds, fetchViews),
{ staleTime: Infinity, enabled: enabled && modelRevisionIds.length > 0 }
);
};
Expand All @@ -51,7 +53,7 @@ export const useFdm3dNodeData = (
modelId: number | undefined,
revisionId: number | undefined,
treeIndex: number | undefined
): UseQueryResult<FdmEdgeWithNode[]> => {
): UseQueryResult<Array<Required<FdmEdgeWithNode>>> => {
const content = useFdmNodeCache();

const enableQuery =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,25 @@ export class RevisionFdmNodeCache {
this._revisionId = revisionId;
}

public async getClosestParentFdmData(searchTreeIndex: number): Promise<FdmEdgeWithNode[]> {
public async getClosestParentFdmData(
searchTreeIndex: number
): Promise<Array<Required<FdmEdgeWithNode>>> {
const cachedFdmData = this._treeIndexToFdmEdges.get(searchTreeIndex);

if (cachedFdmData !== undefined) {
if (checkDefinedView(cachedFdmData)) {
return cachedFdmData;
}

const cachedFdmEdges = this._treeIndexToFdmEdges.get(searchTreeIndex);

if (cachedFdmEdges !== undefined) {
return await this.getDataWithViewsForFdmEdges(cachedFdmEdges, []);
if (cachedFdmData !== undefined) {
return await this.getDataWithViewsForFdmEdges(cachedFdmData, []);
}

return await this.findNodeDataFromAncestors(searchTreeIndex);
}

private async findNodeDataFromAncestors(treeIndex: TreeIndex): Promise<FdmEdgeWithNode[]> {
private async findNodeDataFromAncestors(
treeIndex: TreeIndex
): Promise<Array<Required<FdmEdgeWithNode>>> {
const { edges, ancestorsWithSameMapping, firstMappedAncestorTreeIndex } =
await this.getClosestParentMapping(treeIndex);

Expand All @@ -64,8 +66,8 @@ export class RevisionFdmNodeCache {

const cachedFdmData = this._treeIndexToFdmEdges.get(firstMappedAncestorTreeIndex);

if (cachedFdmData !== undefined) {
this.setCacheForNodes(ancestorsWithSameMapping, cachedFdmData);
if (checkDefinedView(cachedFdmData)) {
this.setSameCacheForNodes(ancestorsWithSameMapping, cachedFdmData);

return cachedFdmData;
}
Expand All @@ -81,7 +83,7 @@ export class RevisionFdmNodeCache {
return await this.getDataWithViewsForFdmEdges(nodeEdges, ancestorsWithSameMapping);
}

private setCacheForNodes(nodes: Node3D[], nodeData: FdmEdgeWithNode[]): void {
private setSameCacheForNodes(nodes: Node3D[], nodeData: FdmEdgeWithNode[]): void {
nodes.forEach((node) => {
this._treeIndexToFdmEdges.set(node.treeIndex, nodeData);
});
Expand All @@ -90,7 +92,7 @@ export class RevisionFdmNodeCache {
private async getDataWithViewsForFdmEdges(
nodeEdges: Array<{ edge: FdmCadEdge; node: Node3D }>,
ancestorsWithSameMapping: Node3D[]
): Promise<FdmEdgeWithNode[]> {
): Promise<Array<Required<FdmEdgeWithNode>>> {
const nodeInspectionResults = await inspectNodes(
this._fdmClient,
nodeEdges.map((edge) => edge.edge.startNode)
Expand All @@ -101,9 +103,9 @@ export class RevisionFdmNodeCache {
view: nodeInspectionResults.items[ind].inspectionResults.involvedViewsAndContainers.views[0]
}));

ancestorsWithSameMapping.forEach((ancestor) =>
this._treeIndexToFdmEdges.set(ancestor.treeIndex, dataWithViews)
);
ancestorsWithSameMapping.forEach((ancestor) => {
this._treeIndexToFdmEdges.set(ancestor.treeIndex, dataWithViews);
});

return dataWithViews;
}
Expand Down Expand Up @@ -180,11 +182,41 @@ export class RevisionFdmNodeCache {
return ancestorMappings.edges;
}

public async fetchViewsForAllEdges(): Promise<void> {
const allEdgesWithoutView = this.getAllEdges().filter((edge) => edge.view === undefined);

if (allEdgesWithoutView.length === 0) {
return;
}

const nodeInspectionResults = await inspectNodes(
this._fdmClient,
allEdgesWithoutView.map((edge) => edge.edge.startNode)
);

allEdgesWithoutView.forEach((fdmEdgeWithNode, ind) => {
const edgeWithView = {
...fdmEdgeWithNode,
view: nodeInspectionResults.items[ind].inspectionResults.involvedViewsAndContainers.views[0]
};

this.insertTreeIndexMappings(edgeWithView.node.treeIndex, edgeWithView);
});
}

public insertTreeIndexMappings(treeIndex: TreeIndex, edge: FdmEdgeWithNode): void {
const edgeArray = this._treeIndexToFdmEdges.get(treeIndex);

if (edgeArray === undefined) {
this._treeIndexToFdmEdges.set(treeIndex, [edge]);
} else {
const presentEdge = edgeArray?.find((e) => e.node.id === edge.node.id);

if (presentEdge !== undefined) {
presentEdge.view = edge.view;
return;
}

edgeArray.push(edge);
}
}
Expand Down Expand Up @@ -222,3 +254,11 @@ function getAncestorDataForTreeIndex(
firstMappedAncestorTreeIndex: treeIndex
};
}

export function checkDefinedView(
edges?: FdmEdgeWithNode[]
): edges is Array<Required<FdmEdgeWithNode>> {
if (edges === undefined) return false;

return edges?.every((edge): edge is Required<FdmEdgeWithNode> => edge.view !== undefined);
}
2 changes: 1 addition & 1 deletion react-components/src/components/NodeCacheProvider/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { type EdgeItem, type DmsUniqueIdentifier, type Source } from '../../util
import { type InModel3dEdgeProperties } from '../../utilities/globalDataModels';

export type FdmCadEdge = EdgeItem<InModel3dEdgeProperties>;
export type FdmEdgeWithNode = { edge: FdmCadEdge; node: Node3D; view: Source };
export type FdmEdgeWithNode = { edge: FdmCadEdge; node: Node3D; view?: Source };

export type ModelId = number;
export type RevisionId = number;
Expand Down
3 changes: 3 additions & 0 deletions react-components/stories/HighlightNode.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ const StoryContent = ({ resources }: { resources: AddResourceOptions[] }): React
style: { cad: DefaultNodeAppearance.Highlighted }
}
]);

void cameraNavigation.fitCameraToInstance(nodeData.fdmNode.externalId, nodeData.fdmNode.space);

console.log('Clicked node data', nodeData);
}, [nodeData?.fdmNode]);

return (
Expand Down

0 comments on commit bdd5bdd

Please sign in to comment.