-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix SO export sorting algorithm #142078
Fix SO export sorting algorithm #142078
Changes from 2 commits
3601aef
00262b6
6abc46d
f5a999d
1dff5bc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,33 +8,36 @@ | |
|
||
import type { SavedObject } from '@kbn/core-saved-objects-common'; | ||
|
||
const getId = (object: { type: string; id: string }) => `${object.type}:${object.id}`; | ||
|
||
export function sortObjects(savedObjects: SavedObject[]): SavedObject[] { | ||
const path = new Set<SavedObject>(); | ||
const traversed = new Set<string>(); | ||
const sorted = new Set<SavedObject>(); | ||
const objectsByTypeId = new Map( | ||
savedObjects.map((object) => [`${object.type}:${object.id}`, object] as [string, SavedObject]) | ||
savedObjects.map((object) => [getId(object), object] as [string, SavedObject]) | ||
); | ||
|
||
function includeObjects(objects: SavedObject[]) { | ||
for (const object of objects) { | ||
if (path.has(object)) { | ||
const objectId = getId(object); | ||
if (traversed.has(objectId)) { | ||
continue; | ||
} | ||
|
||
const refdObjects = object.references | ||
.map((ref) => objectsByTypeId.get(`${ref.type}:${ref.id}`)) | ||
const objectRefs = object.references | ||
.map((ref) => objectsByTypeId.get(getId(ref))) | ||
.filter((ref): ref is SavedObject => !!ref); | ||
|
||
if (refdObjects.length) { | ||
path.add(object); | ||
includeObjects(refdObjects); | ||
path.delete(object); | ||
traversed.add(objectId); | ||
if (objectRefs.length) { | ||
includeObjects(objectRefs); | ||
Comment on lines
+31
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the significant change of the PR, the rest of the diff in this file is just minor enhancement/cleanup. Previously, we were removing the current object from the 'path' when we're done traversing the children, causing the algo to eventually traverse the whole tree again if the same object is encountered in the tree of another node from a higher level. Once a object has been traversed once, we now keep it in the |
||
} | ||
|
||
sorted.add(object); | ||
} | ||
} | ||
|
||
includeObjects(savedObjects); | ||
|
||
return [...sorted]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried it without the fix, and the test does timeout.