garrensmith commented on a change in pull request #993: Display Mango execution 
statistics, when available
URL: https://github.com/apache/couchdb-fauxton/pull/993#discussion_r142931060
 
 

 ##########
 File path: app/addons/documents/mango/components/ExecutionStats.js
 ##########
 @@ -0,0 +1,127 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy 
of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations 
under
+// the License.
+import React from 'react';
+import { Popover, OverlayTrigger } from 'react-bootstrap';
+
+const TOO_MANY_DOCS_SCANNED_WARNING = "The number of documents examined is 
high in proportion to the number of results returned. Consider adding an index 
to improve this.";
+
+export default class ExecutionStats extends React.Component {
+  constructor (props) {
+    super(props);
+  }
+
+  humanizeDuration(milliseconds) {
+    if (milliseconds < 1000) {
+      return Math.round(milliseconds) + ' ms';
+    }
+    let seconds = milliseconds / 1000;
+    if (seconds < 60) {
+      return Math.floor(seconds) + ' seconds';
+    }
+    const minutes = Math.floor(seconds / 60);
+    seconds = seconds - (minutes * 60);
+
+    return minutes + 'minute, ' + seconds + 'seconds';
+  }
+
+  getWarning(executionStats, warning) {
+    if (executionStats) {
+      // warn if many documents scanned in relation to results returned
+      if (executionStats && executionStats.results_returned) {
+        const docsExamined = executionStats.total_docs_examined || 
executionStats.total_quorum_docs_examined;
+        if (docsExamined / executionStats.results_returned > 10) {
+          return TOO_MANY_DOCS_SCANNED_WARNING;
+        }
+      }
+    }
+
+    return warning;
+  }
+
+  warningPopupComponent(warningText) {
+    if (!!warningText) {
+      return (<div className="warning">
+        <i className="fonticon-attention-circled"></i> {warningText}
+      </div>);
+    }
+  }
+
+  executionStatsLine(title, value, alwaysShow = false, units = "") {
+    const hasValue = value === 0 && !alwaysShow ? "false" : "true";
+    return <div data-status={hasValue}>{title + ": "}<span 
className="value">{value.toLocaleString()} {units}</span></div>;
+  }
+
+  executionStatsPopupComponent(executionStats) {
+    if (!executionStats) return null;
+    return (
+      <div className="execution-stats-popup-component">
+        {/* keys examined always 0 so hide it for now */}
+        {/* {this.executionStatsLine("keys examined", 
executionStats.total_keys_examined)} */}
+        {this.executionStatsLine("documents examined", 
executionStats.total_docs_examined)}
+        {this.executionStatsLine("documents examined (quorum)", 
executionStats.total_quorum_docs_examined)}
+        {this.executionStatsLine("results returned", 
executionStats.results_returned, true)}
+        {this.executionStatsLine("execution time", 
executionStats.execution_time_ms, false, "ms")}
+      </div>
+    );
+  }
+
+  popup(executionStats, warningText) {
+    return (
+      <Popover id="popover-trigger-hover-focus" title="Execution Statistics">
+        <div className="execution-stats-popup">
+          {this.executionStatsPopupComponent(executionStats)}
+          {this.warningPopupComponent(warningText)}
+        </div>
+      </Popover>
+    );
+  }
+
+  render() {
+    const {
+      executionStats,
+      warning
+    } = this.props;
+
+    const warningText = this.getWarning(executionStats, warning);
+
+    let warningComponent = null;
+    if (!!warningText) {
+      warningComponent = <i className="fonticon-attention-circled"></i>;
+    }
+
+    let executionStatsComponent = null;
+    if (executionStats) {
+      executionStatsComponent = (
+        <span className="execution-stats-component">Executed in 
{this.humanizeDuration(executionStats.execution_time_ms)}</span>
+      );
+    } else if (!!warningText) {
+      executionStatsComponent = (
+        <span className="execution-stats-component">Warning</span>
+      );
+    }
+
+    const popup = this.popup(executionStats, warningText);
+    return (
+        <OverlayTrigger trigger={['hover', 'focus']} placement="right" 
overlay={popup}>
 
 Review comment:
   Can you also add click as a trigger. Just in case anyone uses this with a 
touch screen
 
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to