• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (C) 2019 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15import {searchSegment} from '../base/binary_search';
16import {Actions} from '../common/actions';
17import {globals} from './globals';
18
19function setToPrevious(current: number) {
20  let index = current - 1;
21  if (index < 0) {
22    index = globals.currentSearchResults.totalResults - 1;
23  }
24  globals.dispatch(Actions.setSearchIndex({index}));
25}
26
27function setToNext(current: number) {
28  const index =
29      (current + 1) % globals.currentSearchResults.totalResults;
30  globals.dispatch(Actions.setSearchIndex({index}));
31}
32
33export function executeSearch(reverse = false) {
34  const index = globals.state.searchIndex;
35  const vizWindow = globals.frontendLocalState.visibleWindowTime;
36  const startNs = vizWindow.start.nanos;
37  const endNs = vizWindow.end.nanos;
38  const currentTs = globals.currentSearchResults.tsStarts[index];
39
40  // If the value of |globals.currentSearchResults.totalResults| is 0,
41  // it means that the query is in progress or no results are found.
42  if (globals.currentSearchResults.totalResults === 0) {
43    return;
44  }
45
46  // If this is a new search or the currentTs is not in the viewport,
47  // select the first/last item in the viewport.
48  if (index === -1 || currentTs < startNs || currentTs > endNs) {
49    if (reverse) {
50      const [smaller] =
51          searchSegment(globals.currentSearchResults.tsStarts, endNs);
52      // If there is no item in the viewport just go to the previous.
53      if (smaller === -1) {
54        setToPrevious(index);
55      } else {
56        globals.dispatch(Actions.setSearchIndex({index: smaller}));
57      }
58    } else {
59      const [, larger] =
60          searchSegment(globals.currentSearchResults.tsStarts, startNs);
61      // If there is no item in the viewport just go to the next.
62      if (larger === -1) {
63        setToNext(index);
64      } else {
65        globals.dispatch(Actions.setSearchIndex({index: larger}));
66      }
67    }
68  } else {
69    // If the currentTs is in the viewport, increment the index.
70    if (reverse) {
71      setToPrevious(index);
72    } else {
73      setToNext(index);
74    }
75  }
76  selectCurrentSearchResult();
77}
78
79function selectCurrentSearchResult() {
80  const searchIndex = globals.state.searchIndex;
81  const source = globals.currentSearchResults.sources[searchIndex];
82  const currentId = globals.currentSearchResults.sliceIds[searchIndex];
83  const trackId = globals.currentSearchResults.trackIds[searchIndex];
84
85  if (currentId === undefined) return;
86
87  if (source === 'cpu') {
88    globals.dispatch(
89        Actions.selectSlice({id: currentId, trackId, scroll: true}));
90  } else if (source === 'log') {
91    globals.dispatch(Actions.selectLog({id: currentId, trackId, scroll: true}));
92  } else {
93    // Search results only include slices from the slice table for now.
94    // When we include annotations we need to pass the correct table.
95    globals.dispatch(Actions.selectChromeSlice(
96        {id: currentId, trackId, table: 'slice', scroll: true}));
97  }
98}
99