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