diff --git a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/highlight_details_flyout/highlight_details_flyout.test.tsx b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/highlight_details_flyout/highlight_details_flyout.test.tsx index cf8052cbf3580..30a4c1dce1dff 100644 --- a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/highlight_details_flyout/highlight_details_flyout.test.tsx +++ b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/highlight_details_flyout/highlight_details_flyout.test.tsx @@ -11,16 +11,8 @@ describe('Highlight Details Flyout', () => { it('renders', async () => { const props: Props = { onClose: () => {}, - shard: { - aggregations: [], - id: ['test', 'test', 'test'], - searches: [], - color: '#fff', - time: 123, - relative: 100, - }, + shardName: '[test][test]', operation: { - parent: null, breakdown: [ { color: 'test', @@ -48,8 +40,7 @@ describe('Highlight Details Flyout', () => { query_type: 'test', selfTime: 100, time: 100, - children: [], - timePercentage: 100, + timePercentage: '100', hasChildren: false, visible: true, absoluteColor: '123', diff --git a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/highlight_details_flyout/highlight_details_flyout.tsx b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/highlight_details_flyout/highlight_details_flyout.tsx index 6ba39d15b8341..40c17df95456a 100644 --- a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/highlight_details_flyout/highlight_details_flyout.tsx +++ b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/highlight_details_flyout/highlight_details_flyout.tsx @@ -17,11 +17,11 @@ import { import { msToPretty } from '../../utils'; import { HighlightDetailsTable } from './highlight_details_table'; -import { Operation, Shard } from '../../types'; +import { Operation } from '../../types'; export interface Props { - operation: Operation; - shard: Shard; + operation: Omit; + shardName: string; indexName: string; onClose: () => void; } @@ -39,14 +39,12 @@ const FlyoutEntry = ({ ); -export const HighlightDetailsFlyout = ({ indexName, operation, shard, onClose }: Props) => { +export const HighlightDetailsFlyout = ({ indexName, operation, shardName, onClose }: Props) => { return ( onClose()}> {indexName} - - [{/* shard id */ shard.id[0]}][{/* shard number */ shard.id[2]}] - + {shardName} diff --git a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/highlight_details_flyout/highlight_details_table.tsx b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/highlight_details_flyout/highlight_details_table.tsx index 4bfa7365de1ef..f41088b7c9b78 100644 --- a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/highlight_details_flyout/highlight_details_table.tsx +++ b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/highlight_details_flyout/highlight_details_table.tsx @@ -36,7 +36,7 @@ export const HighlightDetailsTable = ({ breakdown }: Props) => { { name: 'Percentage', render: (item: BreakdownItem) => ( - + ), }, ]; diff --git a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/percentage_badge.tsx b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/percentage_badge.tsx index 4b53b2e3c18c5..e39e37e8656db 100644 --- a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/percentage_badge.tsx +++ b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/percentage_badge.tsx @@ -9,7 +9,7 @@ import { EuiBadge } from '@elastic/eui'; import classNames from 'classnames'; interface Props { - timePercentage: number; + timePercentage: string; label: string; valueType?: 'percent' | 'time'; } diff --git a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/__tests__/fixtures/normalize_times.ts b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/__tests__/fixtures/normalize_times.ts index 714b856b54c68..f26de49138f12 100644 --- a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/__tests__/fixtures/normalize_times.ts +++ b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/__tests__/fixtures/normalize_times.ts @@ -1,802 +1,809 @@ export const inputTimes = [ { - type:"BooleanQuery", - description:"hour:1 hour:2 #MatchNoDocsQuery[\"User requested \"match_none\" query.\"]", - time:0.447365, - breakdown:[ + type: 'BooleanQuery', + description: 'hour:1 hour:2 #MatchNoDocsQuery["User requested "match_none" query."]', + time: 0.447365, + breakdown: [ { - key:"create_weight", - time:401690, - relative:"89.8", - color:"#feb6b6", - tip:"The time taken to create the Weight object, which holds temporary information during scoring." + key: 'create_weight', + time: 401690, + relative: '89.8', + color: '#feb6b6', + tip: + 'The time taken to create the Weight object, which holds temporary information during scoring.', }, { - key:"build_scorer", - time:45672, - relative:"10.2", - color:"#f6eeee", - tip:"The time taken to create the Scoring object, which is later used to execute the actual scoring of each doc." + key: 'build_scorer', + time: 45672, + relative: '10.2', + color: '#f6eeee', + tip: + 'The time taken to create the Scoring object, which is later used to execute the actual scoring of each doc.', }, { - key:"build_scorer_count", - time:2, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'build_scorer_count', + time: 2, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"create_weight_count", - time:1, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'create_weight_count', + time: 1, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"next_doc", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to advance the iterator to the next matching document." + key: 'next_doc', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken to advance the iterator to the next matching document.', }, { - key:"match", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to execute a secondary, more precise scoring phase (used by phrase queries)." + key: 'match', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: + 'The time taken to execute a secondary, more precise scoring phase (used by phrase queries).', }, { - key:"match_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'match_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"next_doc_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'next_doc_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"score_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'score_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"score", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken in actually scoring the document against the query." + key: 'score', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken in actually scoring the document against the query.', }, { - key:"advance", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to advance the iterator to the next document." + key: 'advance', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken to advance the iterator to the next document.', }, { - key:"advance_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" - } + key: 'advance_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', + }, ], - "children":[ + children: [ { - type:"TermQuery", - description:"hour:1", - time:0.192502, - breakdown:[ + type: 'TermQuery', + description: 'hour:1', + time: 0.192502, + breakdown: [ { - key:"create_weight", - time:190989, - relative:"99.2", - color:"#ffb0b0", - tip:"The time taken to create the Weight object, which holds temporary information during scoring." + key: 'create_weight', + time: 190989, + relative: '99.2', + color: '#ffb0b0', + tip: + 'The time taken to create the Weight object, which holds temporary information during scoring.', }, { - key:"build_scorer", - time:1510, - relative:"0.8", - color:"#f5f4f4", - tip:"The time taken to create the Scoring object, which is later used to execute the actual scoring of each doc." + key: 'build_scorer', + time: 1510, + relative: '0.8', + color: '#f5f4f4', + tip: + 'The time taken to create the Scoring object, which is later used to execute the actual scoring of each doc.', }, { - key:"build_scorer_count", - time:2, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'build_scorer_count', + time: 2, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"create_weight_count", - time:1, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'create_weight_count', + time: 1, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"next_doc", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to advance the iterator to the next matching document." + key: 'next_doc', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken to advance the iterator to the next matching document.', }, { - key:"match", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to execute a secondary, more precise scoring phase (used by phrase queries)." + key: 'match', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: + 'The time taken to execute a secondary, more precise scoring phase (used by phrase queries).', }, { - key:"match_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'match_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"next_doc_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'next_doc_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"score_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'score_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"score", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken in actually scoring the document against the query." + key: 'score', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken in actually scoring the document against the query.', }, { - key:"advance", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to advance the iterator to the next document." + key: 'advance', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken to advance the iterator to the next document.', }, { - key:"advance_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" - } - ], - id:"3339dca6-c34a-49f3-a534-27e46f238bcd", - parentId:"f1e689b1-dafe-4c2b-9a4d-9bd8f1a53803", - childrenIds:[ - + key: 'advance_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', + }, ], - selfTime:0.192502 + id: '3339dca6-c34a-49f3-a534-27e46f238bcd', + parentId: 'f1e689b1-dafe-4c2b-9a4d-9bd8f1a53803', + childrenIds: [], + selfTime: 0.192502, }, { - type:"TermQuery", - description:"hour:2", - time:0.162608, - breakdown:[ + type: 'TermQuery', + description: 'hour:2', + time: 0.162608, + breakdown: [ { - key:"create_weight", - time:162016, - relative:"99.6", - color:"#ffafaf", - tip:"The time taken to create the Weight object, which holds temporary information during scoring." + key: 'create_weight', + time: 162016, + relative: '99.6', + color: '#ffafaf', + tip: + 'The time taken to create the Weight object, which holds temporary information during scoring.', }, { - key:"build_scorer", - time:589, - relative:"0.4", - color:"#f5f5f5", - tip:"The time taken to create the Scoring object, which is later used to execute the actual scoring of each doc." + key: 'build_scorer', + time: 589, + relative: '0.4', + color: '#f5f5f5', + tip: + 'The time taken to create the Scoring object, which is later used to execute the actual scoring of each doc.', }, { - key:"build_scorer_count", - time:2, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'build_scorer_count', + time: 2, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"create_weight_count", - time:1, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'create_weight_count', + time: 1, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"next_doc", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to advance the iterator to the next matching document." + key: 'next_doc', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken to advance the iterator to the next matching document.', }, { - key:"match", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to execute a secondary, more precise scoring phase (used by phrase queries)." + key: 'match', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: + 'The time taken to execute a secondary, more precise scoring phase (used by phrase queries).', }, { - key:"match_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'match_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"next_doc_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'next_doc_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"score_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'score_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"score", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken in actually scoring the document against the query." + key: 'score', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken in actually scoring the document against the query.', }, { - key:"advance", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to advance the iterator to the next document." + key: 'advance', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken to advance the iterator to the next document.', }, { - key:"advance_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" - } - ], - id:"9b75ecdd-a1da-45eb-8d13-5bc5f472dba3", - parentId:"f1e689b1-dafe-4c2b-9a4d-9bd8f1a53803", - childrenIds:[ - + key: 'advance_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', + }, ], - selfTime:0.162608 + id: '9b75ecdd-a1da-45eb-8d13-5bc5f472dba3', + parentId: 'f1e689b1-dafe-4c2b-9a4d-9bd8f1a53803', + childrenIds: [], + selfTime: 0.162608, }, { - type:"MatchNoDocsQuery", - description:"MatchNoDocsQuery[\"User requested \"match_none\" query.\"]", - time:0.03517, - breakdown:[ + type: 'MatchNoDocsQuery', + description: 'MatchNoDocsQuery["User requested "match_none" query."]', + time: 0.03517, + breakdown: [ { - key:"build_scorer", - time:32522, - relative:"92.5", - color:"#feb4b4", - tip:"The time taken to create the Scoring object, which is later used to execute the actual scoring of each doc." + key: 'build_scorer', + time: 32522, + relative: '92.5', + color: '#feb4b4', + tip: + 'The time taken to create the Scoring object, which is later used to execute the actual scoring of each doc.', }, { - key:"create_weight", - time:2645, - relative:"7.5", - color:"#f6f0f0", - tip:"The time taken to create the Weight object, which holds temporary information during scoring." + key: 'create_weight', + time: 2645, + relative: '7.5', + color: '#f6f0f0', + tip: + 'The time taken to create the Weight object, which holds temporary information during scoring.', }, { - key:"build_scorer_count", - time:2, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'build_scorer_count', + time: 2, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"create_weight_count", - time:1, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'create_weight_count', + time: 1, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"next_doc", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to advance the iterator to the next matching document." + key: 'next_doc', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken to advance the iterator to the next matching document.', }, { - key:"match", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to execute a secondary, more precise scoring phase (used by phrase queries)." + key: 'match', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: + 'The time taken to execute a secondary, more precise scoring phase (used by phrase queries).', }, { - key:"match_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'match_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"next_doc_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'next_doc_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"score_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'score_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"score", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken in actually scoring the document against the query." + key: 'score', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken in actually scoring the document against the query.', }, { - key:"advance", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to advance the iterator to the next document." + key: 'advance', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken to advance the iterator to the next document.', }, { - key:"advance_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" - } - ], - id:"ddf5aa3e-4b22-4332-9d5e-79a6ae0cc9cb", - parentId:"f1e689b1-dafe-4c2b-9a4d-9bd8f1a53803", - childrenIds:[ - + key: 'advance_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', + }, ], - selfTime:0.03517 - } + id: 'ddf5aa3e-4b22-4332-9d5e-79a6ae0cc9cb', + parentId: 'f1e689b1-dafe-4c2b-9a4d-9bd8f1a53803', + childrenIds: [], + selfTime: 0.03517, + }, ], - id:"f1e689b1-dafe-4c2b-9a4d-9bd8f1a53803", - childrenIds:[ - "3339dca6-c34a-49f3-a534-27e46f238bcd", - "9b75ecdd-a1da-45eb-8d13-5bc5f472dba3", - "ddf5aa3e-4b22-4332-9d5e-79a6ae0cc9cb" + id: 'f1e689b1-dafe-4c2b-9a4d-9bd8f1a53803', + childrenIds: [ + '3339dca6-c34a-49f3-a534-27e46f238bcd', + '9b75ecdd-a1da-45eb-8d13-5bc5f472dba3', + 'ddf5aa3e-4b22-4332-9d5e-79a6ae0cc9cb', ], - hasChildren:true, - selfTime:0.057085 - } + hasChildren: true, + selfTime: 0.057085, + }, ]; - export const normalizedTimes = [ { - type:"BooleanQuery", - description:"hour:1 hour:2 #MatchNoDocsQuery[\"User requested \"match_none\" query.\"]", - time:0.447365, - breakdown:[ + type: 'BooleanQuery', + description: 'hour:1 hour:2 #MatchNoDocsQuery["User requested "match_none" query."]', + time: 0.447365, + breakdown: [ { - key:"create_weight", - time:401690, - relative:"89.8", - color:"#feb6b6", - tip:"The time taken to create the Weight object, which holds temporary information during scoring." + key: 'create_weight', + time: 401690, + relative: '89.8', + color: '#feb6b6', + tip: + 'The time taken to create the Weight object, which holds temporary information during scoring.', }, { - key:"build_scorer", - time:45672, - relative:"10.2", - color:"#f6eeee", - tip:"The time taken to create the Scoring object, which is later used to execute the actual scoring of each doc." + key: 'build_scorer', + time: 45672, + relative: '10.2', + color: '#f6eeee', + tip: + 'The time taken to create the Scoring object, which is later used to execute the actual scoring of each doc.', }, { - key:"build_scorer_count", - time:2, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'build_scorer_count', + time: 2, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"create_weight_count", - time:1, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'create_weight_count', + time: 1, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"next_doc", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to advance the iterator to the next matching document." + key: 'next_doc', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken to advance the iterator to the next matching document.', }, { - key:"match", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to execute a secondary, more precise scoring phase (used by phrase queries)." + key: 'match', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: + 'The time taken to execute a secondary, more precise scoring phase (used by phrase queries).', }, { - key:"match_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'match_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"next_doc_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'next_doc_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"score_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'score_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"score", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken in actually scoring the document against the query." + key: 'score', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken in actually scoring the document against the query.', }, { - key:"advance", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to advance the iterator to the next document." + key: 'advance', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken to advance the iterator to the next document.', }, { - key:"advance_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" - } + key: 'advance_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', + }, ], - "children":[ + children: [ { - type:"TermQuery", - description:"hour:1", - time:0.192502, - breakdown:[ + type: 'TermQuery', + description: 'hour:1', + time: 0.192502, + breakdown: [ { - key:"create_weight", - time:190989, - relative:"99.2", - color:"#ffb0b0", - tip:"The time taken to create the Weight object, which holds temporary information during scoring." + key: 'create_weight', + time: 190989, + relative: '99.2', + color: '#ffb0b0', + tip: + 'The time taken to create the Weight object, which holds temporary information during scoring.', }, { - key:"build_scorer", - time:1510, - relative:"0.8", - color:"#f5f4f4", - tip:"The time taken to create the Scoring object, which is later used to execute the actual scoring of each doc." + key: 'build_scorer', + time: 1510, + relative: '0.8', + color: '#f5f4f4', + tip: + 'The time taken to create the Scoring object, which is later used to execute the actual scoring of each doc.', }, { - key:"build_scorer_count", - time:2, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'build_scorer_count', + time: 2, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"create_weight_count", - time:1, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'create_weight_count', + time: 1, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"next_doc", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to advance the iterator to the next matching document." + key: 'next_doc', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken to advance the iterator to the next matching document.', }, { - key:"match", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to execute a secondary, more precise scoring phase (used by phrase queries)." + key: 'match', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: + 'The time taken to execute a secondary, more precise scoring phase (used by phrase queries).', }, { - key:"match_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'match_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"next_doc_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'next_doc_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"score_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'score_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"score", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken in actually scoring the document against the query." + key: 'score', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken in actually scoring the document against the query.', }, { - key:"advance", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to advance the iterator to the next document." + key: 'advance', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken to advance the iterator to the next document.', }, { - key:"advance_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" - } - ], - id:"3339dca6-c34a-49f3-a534-27e46f238bcd", - parentId:"f1e689b1-dafe-4c2b-9a4d-9bd8f1a53803", - childrenIds:[ - + key: 'advance_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', + }, ], - selfTime:0.192502, - timePercentage:"43.03", - absoluteColor:"#f9d7d7", - depth:1 + id: '3339dca6-c34a-49f3-a534-27e46f238bcd', + parentId: 'f1e689b1-dafe-4c2b-9a4d-9bd8f1a53803', + childrenIds: [], + selfTime: 0.192502, + timePercentage: '43.03', + absoluteColor: '#f9d7d7', }, { - type:"TermQuery", - description:"hour:2", - time:0.162608, - breakdown:[ + type: 'TermQuery', + description: 'hour:2', + time: 0.162608, + breakdown: [ { - key:"create_weight", - time:162016, - relative:"99.6", - color:"#ffafaf", - tip:"The time taken to create the Weight object, which holds temporary information during scoring." + key: 'create_weight', + time: 162016, + relative: '99.6', + color: '#ffafaf', + tip: + 'The time taken to create the Weight object, which holds temporary information during scoring.', }, { - key:"build_scorer", - time:589, - relative:"0.4", - color:"#f5f5f5", - tip:"The time taken to create the Scoring object, which is later used to execute the actual scoring of each doc." + key: 'build_scorer', + time: 589, + relative: '0.4', + color: '#f5f5f5', + tip: + 'The time taken to create the Scoring object, which is later used to execute the actual scoring of each doc.', }, { - key:"build_scorer_count", - time:2, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'build_scorer_count', + time: 2, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"create_weight_count", - time:1, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'create_weight_count', + time: 1, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"next_doc", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to advance the iterator to the next matching document." + key: 'next_doc', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken to advance the iterator to the next matching document.', }, { - key:"match", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to execute a secondary, more precise scoring phase (used by phrase queries)." + key: 'match', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: + 'The time taken to execute a secondary, more precise scoring phase (used by phrase queries).', }, { - key:"match_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'match_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"next_doc_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'next_doc_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"score_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'score_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"score", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken in actually scoring the document against the query." + key: 'score', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken in actually scoring the document against the query.', }, { - key:"advance", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to advance the iterator to the next document." + key: 'advance', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken to advance the iterator to the next document.', }, { - key:"advance_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" - } - ], - id:"9b75ecdd-a1da-45eb-8d13-5bc5f472dba3", - parentId:"f1e689b1-dafe-4c2b-9a4d-9bd8f1a53803", - childrenIds:[ - + key: 'advance_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', + }, ], - selfTime:0.162608, - timePercentage:"36.35", - absoluteColor:"#f9dcdc", - depth:1 + id: '9b75ecdd-a1da-45eb-8d13-5bc5f472dba3', + parentId: 'f1e689b1-dafe-4c2b-9a4d-9bd8f1a53803', + childrenIds: [], + selfTime: 0.162608, + timePercentage: '36.35', + absoluteColor: '#f9dcdc', }, { - type:"MatchNoDocsQuery", - description:"MatchNoDocsQuery[\"User requested \"match_none\" query.\"]", - time:0.03517, - breakdown:[ + type: 'MatchNoDocsQuery', + description: 'MatchNoDocsQuery["User requested "match_none" query."]', + time: 0.03517, + breakdown: [ { - key:"build_scorer", - time:32522, - relative:"92.5", - color:"#feb4b4", - tip:"The time taken to create the Scoring object, which is later used to execute the actual scoring of each doc." + key: 'build_scorer', + time: 32522, + relative: '92.5', + color: '#feb4b4', + tip: + 'The time taken to create the Scoring object, which is later used to execute the actual scoring of each doc.', }, { - key:"create_weight", - time:2645, - relative:"7.5", - color:"#f6f0f0", - tip:"The time taken to create the Weight object, which holds temporary information during scoring." + key: 'create_weight', + time: 2645, + relative: '7.5', + color: '#f6f0f0', + tip: + 'The time taken to create the Weight object, which holds temporary information during scoring.', }, { - key:"build_scorer_count", - time:2, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'build_scorer_count', + time: 2, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"create_weight_count", - time:1, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'create_weight_count', + time: 1, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"next_doc", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to advance the iterator to the next matching document." + key: 'next_doc', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken to advance the iterator to the next matching document.', }, { - key:"match", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to execute a secondary, more precise scoring phase (used by phrase queries)." + key: 'match', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: + 'The time taken to execute a secondary, more precise scoring phase (used by phrase queries).', }, { - key:"match_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'match_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"next_doc_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'next_doc_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"score_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" + key: 'score_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', }, { - key:"score", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken in actually scoring the document against the query." + key: 'score', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken in actually scoring the document against the query.', }, { - key:"advance", - time:0, - relative:"0.0", - color:"#f5f5f5", - tip:"The time taken to advance the iterator to the next document." + key: 'advance', + time: 0, + relative: '0.0', + color: '#f5f5f5', + tip: 'The time taken to advance the iterator to the next document.', }, { - key:"advance_count", - time:0, - relative:0, - color:"#f5f5f5", - tip:"" - } - ], - id:"ddf5aa3e-4b22-4332-9d5e-79a6ae0cc9cb", - parentId:"f1e689b1-dafe-4c2b-9a4d-9bd8f1a53803", - childrenIds:[ - + key: 'advance_count', + time: 0, + relative: 0, + color: '#f5f5f5', + tip: '', + }, ], - selfTime:0.03517, - timePercentage:"7.86", - absoluteColor:"#f6efef", - depth:1 - } + id: 'ddf5aa3e-4b22-4332-9d5e-79a6ae0cc9cb', + parentId: 'f1e689b1-dafe-4c2b-9a4d-9bd8f1a53803', + childrenIds: [], + selfTime: 0.03517, + timePercentage: '7.86', + absoluteColor: '#f6efef', + }, ], - id:"f1e689b1-dafe-4c2b-9a4d-9bd8f1a53803", - childrenIds:[ - "3339dca6-c34a-49f3-a534-27e46f238bcd", - "9b75ecdd-a1da-45eb-8d13-5bc5f472dba3", - "ddf5aa3e-4b22-4332-9d5e-79a6ae0cc9cb" + id: 'f1e689b1-dafe-4c2b-9a4d-9bd8f1a53803', + childrenIds: [ + '3339dca6-c34a-49f3-a534-27e46f238bcd', + '9b75ecdd-a1da-45eb-8d13-5bc5f472dba3', + 'ddf5aa3e-4b22-4332-9d5e-79a6ae0cc9cb', ], - hasChildren:true, - selfTime:0.057085, - timePercentage:"100.00", - absoluteColor:"#ffafaf", - depth:0 - } + hasChildren: true, + selfTime: 0.057085, + timePercentage: '100.00', + absoluteColor: '#ffafaf', + }, ]; diff --git a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/__tests__/fixtures/search_response.ts b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/__tests__/fixtures/search_response.ts index b4483cc0fc58e..335c6addd40d7 100644 --- a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/__tests__/fixtures/search_response.ts +++ b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/__tests__/fixtures/search_response.ts @@ -182,6 +182,114 @@ export const searchResponse: any = [ create_weight_count: 1, build_scorer: 17681, }, + children: [ + { + type: 'DocValuesFieldExistsQuery', + description: 'DocValuesFieldExistsQuery [field=_primary_term]', + time_in_nanos: 19795, + breakdown: { + set_min_competitive_score_count: 0, + match_count: 0, + shallow_advance_count: 0, + set_min_competitive_score: 0, + next_doc: 600, + match: 0, + next_doc_count: 5, + score_count: 0, + compute_max_score_count: 0, + compute_max_score: 0, + advance: 378, + advance_count: 3, + score: 0, + build_scorer_count: 6, + create_weight: 1121, + shallow_advance: 0, + create_weight_count: 1, + build_scorer: 17681, + }, + children: [ + { + type: 'DocValuesFieldExistsQuery', + description: 'DocValuesFieldExistsQuery [field=_primary_term]', + time_in_nanos: 19795, + breakdown: { + set_min_competitive_score_count: 0, + match_count: 0, + shallow_advance_count: 0, + set_min_competitive_score: 0, + next_doc: 600, + match: 0, + next_doc_count: 5, + score_count: 0, + compute_max_score_count: 0, + compute_max_score: 0, + advance: 378, + advance_count: 3, + score: 0, + build_scorer_count: 6, + create_weight: 1121, + shallow_advance: 0, + create_weight_count: 1, + build_scorer: 17681, + }, + children: [ + { + type: 'DocValuesFieldExistsQuery', + description: 'DocValuesFieldExistsQuery [field=_primary_term]', + time_in_nanos: 19795, + breakdown: { + set_min_competitive_score_count: 0, + match_count: 0, + shallow_advance_count: 0, + set_min_competitive_score: 0, + next_doc: 600, + match: 0, + next_doc_count: 5, + score_count: 0, + compute_max_score_count: 0, + compute_max_score: 0, + advance: 378, + advance_count: 3, + score: 0, + build_scorer_count: 6, + create_weight: 1121, + shallow_advance: 0, + create_weight_count: 1, + build_scorer: 17681, + }, + children: [ + { + type: 'DocValuesFieldExistsQuery', + description: 'DocValuesFieldExistsQuery [field=_primary_term]', + time_in_nanos: 19795, + breakdown: { + set_min_competitive_score_count: 0, + match_count: 0, + shallow_advance_count: 0, + set_min_competitive_score: 0, + next_doc: 600, + match: 0, + next_doc_count: 5, + score_count: 0, + compute_max_score_count: 0, + compute_max_score: 0, + advance: 378, + advance_count: 3, + score: 0, + build_scorer_count: 6, + create_weight: 1121, + shallow_advance: 0, + create_weight_count: 1, + build_scorer: 17681, + }, + }, + ], + }, + ], + }, + ], + }, + ], }, ], }, diff --git a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/__tests__/init_data.test.ts b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/__tests__/init_data.test.ts index 6cd19947a26bc..78247f0ccf31b 100644 --- a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/__tests__/init_data.test.ts +++ b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/__tests__/init_data.test.ts @@ -5,6 +5,9 @@ */ import { ShardSerialized } from '../../../types'; +jest.mock('../constants', () => ({ + MAX_TREE_DEPTH: 3, +})); import { initDataFor } from '../init_data'; import { searchResponse } from './fixtures/search_response'; @@ -15,6 +18,16 @@ describe('ProfileTree init data', () => { const input: ShardSerialized[] = searchResponse as any; const actual = initDataFor('searches')(input); + /* prettier-ignore */ + expect( + actual[1].shards[0].searches![0] + .treeRoot! // level 0 + .children[0] // level 1 + .children[0] // level 2 + .children[0] // level 3 -- Max level! + .children, // level 4 (nothing here!) + ).toEqual([]); + expect(actual[0].name).toEqual(processedResponseWithFirstShard[0].name); const expectedFirstShard = processedResponseWithFirstShard[0].shards[0]; expect(actual[0].shards[0]).toEqual(expectedFirstShard); diff --git a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/__tests__/unsafe_utils.test.ts b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/__tests__/unsafe_utils.test.ts index 17c7051f09769..ca423310e8375 100644 --- a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/__tests__/unsafe_utils.test.ts +++ b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/__tests__/unsafe_utils.test.ts @@ -17,13 +17,16 @@ describe('normalizeBreakdown', function() { }); }); -describe('normalizeTimes', function() { +describe('normalizeTime', function() { it('returns correct normalization', function() { const totalTime = 0.447365; // Deep clone the object to preserve the original const input = JSON.parse(JSON.stringify(inputTimes)); - util.normalizeTimes(input, totalTime, 0); + + // Simulate recursive application to the tree. + input.forEach((i: any) => util.normalizeTime(i, totalTime)); + input[0].children.forEach((i: any) => util.normalizeTime(i, totalTime)); // Modifies in place, so inputTimes will change expect(input).to.eql(normalizedTimes); diff --git a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/constants.ts b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/constants.ts new file mode 100644 index 0000000000000..b5122f93f1981 --- /dev/null +++ b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/constants.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +// Prevent recursive data structures from blowing up the JS call stack. +export const MAX_TREE_DEPTH = 40; diff --git a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/init_data.ts b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/init_data.ts index 642b2b741abf0..af24a8936c915 100644 --- a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/init_data.ts +++ b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/init_data.ts @@ -4,18 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ -import { produce } from 'immer'; +import cloneDeep from 'lodash.clonedeep'; import { flow } from 'fp-ts/lib/function'; import { Targets, Shard, ShardSerialized } from '../../types'; -import { calcTimes, normalizeTimes, initTree, normalizeIndices, sortIndices } from './unsafe_utils'; +import { calcTimes, initTree, normalizeIndices, sortIndices } from './unsafe_utils'; import { IndexMap } from './types'; /** * Functions prefixed with "mutate" change values by reference. Be careful when using these! - * - * It's recommended to us immer's `produce` functions to ensure immutability. */ - export function mutateAggsTimesTree(shard: Shard) { if (shard.aggregations == null) { shard.time = 0; @@ -26,8 +23,7 @@ export function mutateAggsTimesTree(shard: Shard) { shardTime += totalTime; } for (const agg of shard.aggregations!) { - normalizeTimes([agg], shardTime, 0); - initTree([agg], 0); + initTree([agg], shardTime); } shard.time = shardTime; } @@ -43,66 +39,76 @@ export function mutateSearchTimesTree(shard: Shard) { shard.rewrite_time += search.rewrite_time!; const totalTime = calcTimes(search.query!); shardTime += totalTime; - normalizeTimes(search.query!, totalTime, 0); - initTree(search.query!, 0); + initTree(search.query!, totalTime); search.treeRoot = search.query![0]; + // Remove this object. search.query = null as any; } shard.time = shardTime; } const initShards = (data: ShardSerialized[]) => - produce(data, draft => { - return draft.map(s => { - const idMatch = s.id.match(/\[([^\]\[]*?)\]/g) || []; - const ids = idMatch.map(id => { - return id.replace('[', '').replace(']', ''); - }); - return { - ...s, - id: ids, - time: 0, - color: '', - relative: 0, - }; + data.map(s => { + const idMatch = s.id.match(/\[([^\]\[]*?)\]/g) || []; + const ids = idMatch.map(id => { + return id.replace('[', '').replace(']', ''); }); + return { + ...s, + id: ids, + time: 0, + color: '', + relative: 0, + }; }); -export const calculateShardValues = (target: Targets) => (data: Shard[]) => - produce(data, draft => { - for (const shard of draft) { - if (target === 'searches') { - mutateSearchTimesTree(shard); - } else if (target === 'aggregations') { - mutateAggsTimesTree(shard); - } +export const calculateShardValues = (target: Targets) => (data: Shard[]) => { + const mutateTimesTree = + target === 'searches' + ? mutateSearchTimesTree + : target === 'aggregations' + ? mutateAggsTimesTree + : null; + + if (mutateTimesTree) { + for (const shard of data) { + mutateTimesTree(shard); } - }); + } -export const initIndices = (data: Shard[]) => - produce(data, doNotChange => { - const indices: IndexMap = {}; + return data; +}; - for (const shard of doNotChange) { - if (!indices[shard.id[1]]) { - indices[shard.id[1]] = { - shards: [], - time: 0, - name: shard.id[1], - visible: false, - }; - } - indices[shard.id[1]].shards.push(shard); - indices[shard.id[1]].time += shard.time; +export const initIndices = (data: Shard[]) => { + const indices: IndexMap = {}; + + for (const shard of data) { + if (!indices[shard.id[1]]) { + indices[shard.id[1]] = { + shards: [], + time: 0, + name: shard.id[1], + visible: false, + }; } + indices[shard.id[1]].shards.push(shard); + indices[shard.id[1]].time += shard.time; + } - return indices; - }); + return indices; +}; -export const normalize = (target: Targets) => (data: IndexMap) => - produce(data, draft => { - normalizeIndices(draft, target); - }); +export const normalize = (target: Targets) => (data: IndexMap) => { + normalizeIndices(data, target); + return data; +}; export const initDataFor = (target: Targets) => - flow(initShards, calculateShardValues(target), initIndices, normalize(target), sortIndices); + flow( + cloneDeep, + initShards, + calculateShardValues(target), + initIndices, + normalize(target), + sortIndices + ); diff --git a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/shard_details/shard_details.tsx b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/shard_details/shard_details.tsx index eca2d1994f8c5..5ca8ad4ecd979 100644 --- a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/shard_details/shard_details.tsx +++ b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/shard_details/shard_details.tsx @@ -38,7 +38,7 @@ export const ShardDetails = ({ index, shard, operations }: Props) => { diff --git a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/shard_details/shard_details_tree_node.tsx b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/shard_details/shard_details_tree_node.tsx index 75da10f8aca2e..1d8f915d3d47d 100644 --- a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/shard_details/shard_details_tree_node.tsx +++ b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/shard_details/shard_details_tree_node.tsx @@ -28,8 +28,7 @@ const limitString = (string: string, limit: number) => `${string.slice(0, limit)}${string.length > limit ? '...' : ''}`; /** - * This is a component that recursively iterates over data to render out a tree like - * structure in a flatly. + * This component recursively renders a tree */ export const ShardDetailsTreeNode = ({ operation, index, shard }: Props) => { const [childrenVisible, setChildrenVisible] = useState(hasVisibleChild(operation)); @@ -106,7 +105,7 @@ export const ShardDetailsTreeNode = ({ operation, index, shard }: Props) => { {childrenVisible && operation.hasChildren && - operation.children.flatMap((childOp, idx) => ( + operation.children.map((childOp, idx) => ( ))} diff --git a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/unsafe_utils.ts b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/unsafe_utils.ts index fc21c5da37764..2201ad42070b7 100644 --- a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/unsafe_utils.ts +++ b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/unsafe_utils.ts @@ -4,13 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { produce } from 'immer'; import { i18n } from '@kbn/i18n'; import tinycolor from 'tinycolor2'; import _ from 'lodash'; import { BreakdownItem, Index, Operation, Shard, Targets } from '../../types'; import { IndexMap } from './types'; +import { MAX_TREE_DEPTH } from './constants'; export const comparator = (v1: number, v2: number) => { if (v1 < v2) { @@ -53,16 +53,16 @@ function getToolTip(key: string) { } } -export function timeInMilliseconds(data: any) { +export function timeInMilliseconds(data: any): number { if (data.time_in_nanos) { return data.time_in_nanos / 1000000; } if (typeof data.time === 'string') { - return data.time.replace('ms', ''); + return Number(data.time.replace('ms', '')); } - return data.time; + return Number(data.time); } export function calcTimes(data: any[], parentId?: string) { @@ -117,21 +117,6 @@ export function normalizeBreakdown(breakdown: Record) { }); } -export function normalizeTimes(data: any[], totalTime: number, depth: number) { - // Second pass to normalize - for (const child of data) { - child.timePercentage = ((timeInMilliseconds(child) / totalTime) * 100).toFixed(2); - child.absoluteColor = tinycolor.mix('#F5F5F5', '#FFAFAF', child.timePercentage).toHexString(); - child.depth = depth; - - if (child.children != null && child.children.length !== 0) { - normalizeTimes(child.children, totalTime, depth + 1); - } - } - - data.sort((a, b) => comparator(timeInMilliseconds(a), timeInMilliseconds(b))); -} - export function normalizeIndices(indices: IndexMap, target: Targets) { // Sort the shards per-index let sortQueryComponents; @@ -167,7 +152,26 @@ export function normalizeIndices(indices: IndexMap, target: Targets) { } } -export function initTree(data: Operation[], depth = 0, parent: Operation | null = null) { +export function normalizeTime(operation: Operation, totalTime: number) { + operation.timePercentage = ((timeInMilliseconds(operation) / totalTime) * 100).toFixed(2); + operation.absoluteColor = tinycolor + .mix('#F5F5F5', '#FFAFAF', +operation.timePercentage) + .toHexString(); +} + +export function initTree( + data: Operation[], + totalTime: number, + depth = 0, + parent: Operation | null = null +) { + if (MAX_TREE_DEPTH + 1 === depth) { + if (parent) { + parent!.hasChildren = false; + parent!.children = []; + } + return; + } for (const child of data) { // For bwc of older profile responses if (!child.description) { @@ -178,44 +182,28 @@ export function initTree(data: Operation[], depth = 0, parent: Operation | nu child.query_type = null; } - // Use named function for tests. + normalizeTime(child, totalTime); child.parent = parent; child.time = timeInMilliseconds(child); child.lucene = child.description; child.query_type = child.type!.split('.').pop()!; - child.visible = child.timePercentage > 20; + child.visible = +child.timePercentage > 20; child.depth = depth; if (child.children != null && child.children.length !== 0) { - initTree(child.children, depth + 1, child); + initTree(child.children, totalTime, depth + 1, child); } } -} - -export function closeNode(node: Operation) { - const closeDraft = (draft: Operation) => { - draft.visible = false; - if (draft.children == null || draft.children.length === 0) { - return; - } - - for (const child of draft.children) { - closeDraft(child); - } - }; - return produce(node, draft => { - closeDraft(draft); - }); + data.sort((a, b) => comparator(timeInMilliseconds(a), timeInMilliseconds(b))); } -export const sortIndices = (data: IndexMap) => - produce(data, doNotChange => { - const sortedIndices: Index[] = []; - for (const index of Object.values(doNotChange)) { - sortedIndices.push(index); - } - // And now sort the indices themselves - sortedIndices.sort((a, b) => comparator(a.time, b.time)); - return sortedIndices; - }); +export const sortIndices = (data: IndexMap) => { + const sortedIndices: Index[] = []; + for (const index of Object.values(data)) { + sortedIndices.push(index); + } + // And now sort the indices themselves + sortedIndices.sort((a, b) => comparator(a.time, b.time)); + return sortedIndices; +}; diff --git a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/store/reducer.test.ts b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/store/reducer.test.ts new file mode 100644 index 0000000000000..14424a1c88529 --- /dev/null +++ b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/store/reducer.test.ts @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { reducer } from './reducer'; +import { initialState, State } from './store'; + +describe('Searchprofiler store reducer', () => { + let state: State; + + beforeEach(() => { + state = initialState; + }); + + it('profiles as expected', () => { + const nextState = reducer(state, { type: 'setProfiling', value: true }); + + expect(nextState).toEqual({ + ...state, + pristine: false, + profiling: true, + } as State); + + const finalState = reducer(nextState, { type: 'setProfiling', value: false }); + + expect(finalState).toEqual({ + ...nextState, + pristine: false, + profiling: false, + } as State); + }); + + it('highlights as expected', () => { + const op = { children: null } as any; + const shard = { id: ['a', 'b', 'c'] } as any; + const nextState = reducer(state, { + type: 'setHighlightDetails', + value: { operation: op, indexName: 'test', shard }, + }); + + expect(nextState).toEqual({ + ...state, + highlightDetails: { + operation: { + /* .children no longer defined */ + }, + shardName: '[a][c]', + indexName: 'test', + }, + }); + + const finalState = reducer(state, { + type: 'setHighlightDetails', + value: null, + }); + + expect(finalState).toEqual({ ...state, highlightDetails: null }); + }); +}); diff --git a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/store/reducer.ts b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/store/reducer.ts index 615511786afd1..394110ac49524 100644 --- a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/store/reducer.ts +++ b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/store/reducer.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { produce } from 'immer'; import { Reducer } from 'react'; import { State } from './store'; @@ -17,36 +16,49 @@ export type Action = | { type: 'setActiveTab'; value: Targets | null } | { type: 'setCurrentResponse'; value: ShardSerialized[] | null }; -export const reducer: Reducer = (state, action) => - produce(state, draft => { - if (action.type === 'setProfiling') { - draft.pristine = false; - draft.profiling = action.value; - if (draft.profiling) { - draft.currentResponse = null; - draft.highlightDetails = null; - } - return; - } +export const reducer: Reducer = (state, action) => { + const nextState = { ...state }; - if (action.type === 'setHighlightDetails') { - draft.highlightDetails = action.value; - return; + if (action.type === 'setProfiling') { + nextState.pristine = false; + nextState.profiling = action.value; + if (nextState.profiling) { + nextState.currentResponse = null; + nextState.highlightDetails = null; } + return nextState; + } - if (action.type === 'setActiveTab') { - draft.activeTab = action.value; - return; + if (action.type === 'setHighlightDetails') { + if (action.value) { + const value = action.value; + // Exclude children to avoid unnecessary work copying a recursive structure. + const { children, parent, ...restOfOperation } = value.operation; + nextState.highlightDetails = { + indexName: value.indexName, + operation: Object.freeze(restOfOperation), + // prettier-ignore + shardName: `[${/* shard id */value.shard.id[0]}][${/* shard number */value.shard.id[2] }]` + }; + } else { + nextState.highlightDetails = null; } + return nextState; + } + + if (action.type === 'setActiveTab') { + nextState.activeTab = action.value; + return nextState; + } - if (action.type === 'setCurrentResponse') { - draft.currentResponse = action.value; - if (draft.currentResponse) { - // Default to the searches tab - draft.activeTab = 'searches'; - } - return; + if (action.type === 'setCurrentResponse') { + nextState.currentResponse = action.value; + if (nextState.currentResponse) { + // Default to the searches tab + nextState.activeTab = 'searches'; } + return nextState; + } - throw new Error(`Unknown action: ${action}`); - }); + throw new Error(`Unknown action: ${action}`); +}; diff --git a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/store/store.ts b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/store/store.ts index 7008854a16285..45194ff917c93 100644 --- a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/store/store.ts +++ b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/store/store.ts @@ -5,13 +5,20 @@ */ import { useReducer } from 'react'; import { reducer } from './reducer'; -import { ShardSerialized, Targets } from '../types'; -import { OnHighlightChangeArgs } from '../components/profile_tree'; +import { Operation, ShardSerialized, Targets } from '../types'; + +export type OperationNoChildParent = Omit; + +interface HighlightDetails { + indexName: string; + operation: OperationNoChildParent; + shardName: string; +} export interface State { profiling: boolean; pristine: boolean; - highlightDetails: OnHighlightChangeArgs | null; + highlightDetails: HighlightDetails | null; activeTab: Targets | null; currentResponse: ShardSerialized[] | null; } diff --git a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/types.ts b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/types.ts index 2b4dc01c45d6f..9866f8d5b1ccb 100644 --- a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/types.ts +++ b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/types.ts @@ -42,7 +42,7 @@ export interface Operation { hasChildren: boolean; visible: boolean; selfTime: number; - timePercentage: number; + timePercentage: string; absoluteColor: string; time: number;