Skip to content

Commit 0ab7363

Browse files
authored
Merge pull request #1777 from RedisInsight/fe/bugfix-RI-3726_profile_explain-RI-4223
#RI-4223 Fe/bugfix ri 3726 profile explain
2 parents b6889af + ff6b6a3 commit 0ab7363

File tree

3 files changed

+125
-78
lines changed

3 files changed

+125
-78
lines changed

redisinsight/ui/src/packages/ri-explain/src/Explain.tsx

Lines changed: 87 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ function getEdgeColor(isDarkTheme: boolean) {
4848

4949
export default function Explain(props: IExplain): JSX.Element {
5050
const command = props.command.split(' ')[0].toLowerCase()
51-
5251
if (command.startsWith('graph')) {
5352
const info = props.data[0].response
5453
const resp = ParseGraphV2(info)
@@ -83,6 +82,15 @@ export default function Explain(props: IExplain): JSX.Element {
8382
let [cluster, entityInfo] = ParseProfileCluster(info)
8483
cluster['Coordinator'].forEach((kv: [string, string]) => profilingTime[kv[0]] = kv[1])
8584
data = entityInfo
85+
} else if (typeof info[0] === 'string' && info[0].toLowerCase().startsWith('coordinator')) {
86+
const resultsProfile = info[2]
87+
data = ParseProfile(resultsProfile)
88+
profilingTime = {
89+
'Total Coordinator time': info[4],
90+
'Total profile time': resultsProfile[0][1],
91+
'Parsing time': resultsProfile[1][1],
92+
'Pipeline creation time': resultsProfile[2][1],
93+
}
8694
} else {
8795
data = ParseProfile(info)
8896
profilingTime = {
@@ -140,7 +148,7 @@ function ExplainDraw({data, type, module, profilingTime}: {data: any, type: Core
140148
const container = useRef<HTMLDivElement | null>(null)
141149

142150
const [done, setDone] = useState(false)
143-
const [collapse, setCollapse] = useState(true)
151+
const [collapse, setCollapse] = useState(type !== CoreType.Profile)
144152
const [isFullScreen, setIsFullScreen] = useState(false)
145153
const [core, setCore] = useState<Graph>()
146154

@@ -151,15 +159,15 @@ function ExplainDraw({data, type, module, profilingTime}: {data: any, type: Core
151159
if (isFullScreen) {
152160
setIsFullScreen(true)
153161
const height = Math.max((b?.height || 585) + 100, parent.document.body.offsetHeight)
154-
if (collapse) {
162+
if (type !== CoreType.Profile && collapse) {
155163
core?.resize(width, window.outerHeight - 250)
156164
core?.positionContent("top")
157165
} else {
158166
core?.resize(width, height)
159167
}
160168
} else {
161169
setIsFullScreen(false)
162-
if (collapse) {
170+
if (type !== CoreType.Profile && collapse) {
163171
core?.resize(width, 400)
164172
core?.positionContent("top")
165173
} else {
@@ -236,45 +244,6 @@ function ExplainDraw({data, type, module, profilingTime}: {data: any, type: Core
236244
})
237245
})
238246

239-
const ele = document.querySelector("#container-parent")
240-
241-
let pos = { top: 0, left: 0, x: 0, y: 0 }
242-
243-
const mouseMoveHandler = function (e) {
244-
// How far the mouse has been moved
245-
const dx = e.clientX - pos.x
246-
const dy = e.clientY - pos.y
247-
248-
// Scroll the element
249-
if (ele) {
250-
ele.scrollTop = pos.top - dy
251-
ele.scrollLeft = pos.left - dx
252-
}
253-
}
254-
255-
256-
const mouseUpHandler = function () {
257-
document.removeEventListener('mousemove', mouseMoveHandler)
258-
document.removeEventListener('mouseup', mouseUpHandler)
259-
}
260-
261-
262-
const mouseDownHandler = function (e) {
263-
pos = {
264-
// The current scroll
265-
left: ele?.scrollLeft || 0,
266-
top: ele?.scrollTop || 0,
267-
// Get the current mouse position
268-
x: e.clientX,
269-
y: e.clientY,
270-
}
271-
272-
document.addEventListener('mousemove', mouseMoveHandler)
273-
setTimeout(() => document.addEventListener('mouseup', mouseUpHandler), 100)
274-
}
275-
276-
ele?.addEventListener('mousedown', mouseDownHandler)
277-
278247
resize()
279248

280249
const result = Hierarchy.compactBox(data, {
@@ -426,7 +395,47 @@ function ExplainDraw({data, type, module, profilingTime}: {data: any, type: Core
426395

427396
}, [done])
428397

429-
if (collapse) {
398+
const ele = document.querySelector("#container-parent")
399+
400+
let pos = { top: 0, left: 0, x: 0, y: 0 }
401+
402+
const mouseMoveHandler = function (e) {
403+
// How far the mouse has been moved
404+
const dx = e.clientX - pos.x
405+
const dy = e.clientY - pos.y
406+
407+
// Scroll the element
408+
if (ele) {
409+
ele.scrollTop = pos.top - dy
410+
ele.scrollLeft = pos.left - dx
411+
}
412+
}
413+
414+
415+
const mouseUpHandler = function () {
416+
document.removeEventListener('mousemove', mouseMoveHandler)
417+
document.removeEventListener('mouseup', mouseUpHandler)
418+
}
419+
420+
421+
const mouseDownHandler = function (e) {
422+
pos = {
423+
// The current scroll
424+
left: ele?.scrollLeft || 0,
425+
top: ele?.scrollTop || 0,
426+
// Get the current mouse position
427+
x: e.clientX,
428+
y: e.clientY,
429+
}
430+
431+
document.addEventListener('mousemove', mouseMoveHandler)
432+
setTimeout(() => document.addEventListener('mouseup', mouseUpHandler), 100)
433+
}
434+
435+
ele?.addEventListener('mousedown', mouseDownHandler)
436+
437+
438+
if (type !== CoreType.Profile && collapse) {
430439
core?.resize(undefined, isFullScreen ? (window.outerHeight - 250) : 400)
431440
core?.positionContent("top")
432441
} else {
@@ -435,23 +444,24 @@ function ExplainDraw({data, type, module, profilingTime}: {data: any, type: Core
435444

436445
return (
437446
<div>
438-
{ collapse && <div style={{ paddingTop: '50px' }}></div> }
447+
{ type !== CoreType.Profile && collapse && <div style={{ paddingTop: '50px' }}></div> }
439448
<div
440449
id="container-parent"
441450
style={{
442-
height: isFullScreen ? (window.outerHeight - 170) + 'px' : collapse ? '500px' : '585px',
451+
height: isFullScreen ? (window.outerHeight - 170) + 'px' : type !== CoreType.Profile && collapse ? '500px' : '585px',
443452
width: '100%',
444453
overflow: 'auto',
445454
}}
446455
>
447456
<div style={{ margin: 0, width: '100vw' }} ref={container} id="container" />
448-
{ !collapse && (
457+
{ !(collapse) && (
449458
<div className="ZoomMenu">
450459
{
451460
[
452461
{
453462
name: 'Zoom In',
454463
onClick: () => {
464+
setTimeout(() => document.addEventListener('mouseup', mouseUpHandler), 100)
455465
core?.zoom(0.5)
456466
core?.resize(undefined, core?.getContentBBox().height + 50)
457467
},
@@ -460,6 +470,7 @@ function ExplainDraw({data, type, module, profilingTime}: {data: any, type: Core
460470
{
461471
name: 'Zoom Out',
462472
onClick: () => {
473+
setTimeout(() => document.addEventListener('mouseup', mouseUpHandler), 100)
463474
core && Math.floor(core.zoom()) <= 0.5 ? core?.zoom(0) : core?.zoom(-0.5)
464475
core?.resize(undefined, core?.getContentBBox().height + 50)
465476
},
@@ -468,6 +479,7 @@ function ExplainDraw({data, type, module, profilingTime}: {data: any, type: Core
468479
{
469480
name: 'Reset Zoom',
470481
onClick: () => {
482+
setTimeout(() => document.addEventListener('mouseup', mouseUpHandler), 100)
471483
core?.zoomTo(1)
472484
core?.resize(undefined, core?.getContentBBox().height + 50)
473485
},
@@ -486,32 +498,35 @@ function ExplainDraw({data, type, module, profilingTime}: {data: any, type: Core
486498
}
487499
</div>
488500
)}
489-
<div
490-
style={{ paddingBottom: (isFullScreen && profilingTime && ModuleType.Search ? '60px' : '35px')}}
491-
className="CollapseButton"
492-
onClick={e => {
493-
e.preventDefault()
494-
if (!collapse) { // About to collapse?
495-
core?.zoomTo(1)
496-
core?.resize(undefined, core?.getContentBBox().height + 50)
501+
{ type !== CoreType.Profile &&
502+
<div
503+
style={{ paddingBottom: (isFullScreen && profilingTime && ModuleType.Search ? '60px' : '35px')}}
504+
className="CollapseButton"
505+
onClick={e => {
506+
e.preventDefault()
507+
setTimeout(() => document.addEventListener('mouseup', mouseUpHandler), 100)
508+
if (!collapse) { // About to collapse?
509+
core?.zoomTo(1)
510+
core?.resize(undefined, core?.getContentBBox().height + 50)
511+
}
512+
setCollapse(!collapse)
513+
}}
514+
>
515+
{
516+
collapse
517+
?
518+
<>
519+
<div>Expand</div>
520+
<EuiIcon className="NodeIcon" size="m" type="arrowDown" />
521+
</>
522+
:
523+
<>
524+
<div>Collapse</div>
525+
<EuiIcon className="NodeIcon" size="m" type="arrowUp" />
526+
</>
497527
}
498-
setCollapse(!collapse)
499-
}}
500-
>
501-
{
502-
collapse
503-
?
504-
<>
505-
<div>Expand</div>
506-
<EuiIcon className="NodeIcon" size="m" type="arrowDown" />
507-
</>
508-
:
509-
<>
510-
<div>Collapse</div>
511-
<EuiIcon className="NodeIcon" size="m" type="arrowUp" />
512-
</>
513-
}
514-
</div>
528+
</div>
529+
}
515530
{ profilingTime &&
516531
(
517532
module === ModuleType.Search &&

redisinsight/ui/src/packages/ri-explain/src/Node.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export function ExplainNode(props: INodeProps) {
3131
<div className="InfoData">
3232
<EuiToolTip delay='long' content={infoData}><span>{infoData}</span></EuiToolTip>
3333
</div>
34-
{subType && [EntityType.GEO, EntityType.NUMERIC, EntityType.TEXT, EntityType.TAG].includes(subType) && <div className="Type">{subType}</div> }
34+
{subType && [EntityType.GEO, EntityType.NUMERIC, EntityType.TEXT, EntityType.TAG, EntityType.FUZZY].includes(subType) && <div className="Type">{subType}</div> }
3535
</div>
3636
</div>
3737
{

redisinsight/ui/src/packages/ri-explain/src/parser.ts

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ enum TokenType {
99

1010
UNION = 'UNION',
1111
INTERSECT = 'INTERSECT',
12+
FUZZY_EXPR = 'FUZZY_EXPR',
1213
GEO_EXPR = 'GEO_EXPR',
1314
TAG_EXPR = 'TAG_EXPR',
1415
NUMERIC = 'NUMERIC',
@@ -182,6 +183,8 @@ class Lexer {
182183
let tokenType = KEYWORDS[literal] || TokenType.IDENTIFIER
183184
if (literal.startsWith('TAG:')) {
184185
tokenType = TokenType.TAG_EXPR
186+
} else if (literal === 'FUZZY') {
187+
tokenType = TokenType.FUZZY_EXPR
185188
} else if (literal === 'GEO') {
186189
tokenType = TokenType.GEO_EXPR
187190
} else if (literal.startsWith('@') && literal.endsWith(':UNION')) {
@@ -212,6 +215,7 @@ export enum EntityType {
212215

213216
// These are used exclusively in FT.PROFILE
214217
GEO = 'GEO',
218+
FUZZY = 'FUZZY',
215219
TEXT = 'TEXT',
216220
TAG = 'TAG',
217221

@@ -467,7 +471,9 @@ class Parser {
467471
} else if (this.CurrentToken.T === TokenType.TAG_EXPR) {
468472
Exprs.push(this.parseTagExpr())
469473
} else if (this.CurrentToken.T === TokenType.GEO_EXPR) {
470-
Exprs.push(this.parseTagExpr())
474+
Exprs.push(this.parseGeoExpr())
475+
} else if (this.CurrentToken.T === TokenType.FUZZY_EXPR) {
476+
Exprs.push(this.parseFuzzyExpr())
471477
}
472478

473479
this.nextToken()
@@ -513,7 +519,9 @@ class Parser {
513519
} else if (this.CurrentToken.T === TokenType.TAG_EXPR) {
514520
Exprs.push(this.parseTagExpr())
515521
} else if (this.CurrentToken.T === TokenType.GEO_EXPR) {
516-
Exprs.push(this.parseTagExpr())
522+
Exprs.push(this.parseGeoExpr())
523+
} else if (this.CurrentToken.T === TokenType.FUZZY_EXPR) {
524+
Exprs.push(this.parseFuzzyExpr())
517525
}
518526

519527
this.nextToken()
@@ -536,6 +544,28 @@ class Parser {
536544
return new Expr(str, EntityType.TEXT)
537545
}
538546

547+
parseFuzzyExpr() {
548+
assertToken(TokenType.FUZZY_EXPR, this.CurrentToken.T)
549+
550+
this.nextToken()
551+
552+
assertToken(TokenType.LBRACE, this.CurrentToken.T)
553+
554+
this.nextToken()
555+
556+
assertToken(TokenType.IDENTIFIER, this.CurrentToken.T)
557+
558+
let identifierData = this.CurrentToken.Data;
559+
560+
this.nextToken()
561+
562+
assertToken(TokenType.RBRACE, this.CurrentToken?.T)
563+
564+
this.nextToken()
565+
566+
return new Expr(identifierData, EntityType.FUZZY)
567+
}
568+
539569
parseGeoExpr() {
540570
assertToken(TokenType.GEO_EXPR, this.CurrentToken.T)
541571

@@ -712,6 +742,8 @@ function Parse(data: string): SearchExpr {
712742
return p.parseTagExpr()
713743
} else if (p.CurrentToken.T === TokenType.GEO_EXPR) {
714744
return p.parseGeoExpr()
745+
} else if (p.CurrentToken.T === TokenType.FUZZY_EXPR) {
746+
return p.parseFuzzyExpr()
715747
} else {
716748
return p.parseExpr()
717749
}
@@ -793,7 +825,7 @@ export function ParseProfileCluster(info: any[]): [Object, EntityInfo] {
793825

794826
export function ParseProfile(info: any[][]): EntityInfo {
795827
const parserData: any = info[info.length - 2]
796-
let resp = ParseIteratorProfile(parserData[1])
828+
let resp = parserData[0].toLowerCase().startsWith('iterators') ? ParseIteratorProfile(parserData[1]) : null
797829

798830
const processorsProfile: string[][] = info[info.length - 1].slice(1)
799831

@@ -805,11 +837,11 @@ export function ParseProfile(info: any[][]): EntityInfo {
805837
type: e[1] as EntityType,
806838
time: e[3],
807839
counter: e[5],
808-
children: [{...resp, parentId: id}],
840+
children: resp ? [{...resp, parentId: id}] : [],
809841
}
810842
}
811843

812-
return resp
844+
return resp as EntityInfo
813845
}
814846

815847
export function ParseIteratorProfile(data: any[]): EntityInfo {

0 commit comments

Comments
 (0)