1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.people.data; 18 19 import android.annotation.NonNull; 20 21 import java.util.ArrayList; 22 import java.util.List; 23 import java.util.Set; 24 25 /** An {@link EventHistory} that aggregates multiple {@link EventHistory}. */ 26 class AggregateEventHistoryImpl implements EventHistory { 27 28 private final List<EventHistory> mEventHistoryList = new ArrayList<>(); 29 30 @NonNull 31 @Override getEventIndex(int eventType)32 public EventIndex getEventIndex(int eventType) { 33 for (EventHistory eventHistory : mEventHistoryList) { 34 EventIndex eventIndex = eventHistory.getEventIndex(eventType); 35 if (!eventIndex.isEmpty()) { 36 return eventIndex; 37 } 38 } 39 return EventIndex.EMPTY; 40 } 41 42 @NonNull 43 @Override getEventIndex(Set<Integer> eventTypes)44 public EventIndex getEventIndex(Set<Integer> eventTypes) { 45 EventIndex merged = null; 46 for (EventHistory eventHistory : mEventHistoryList) { 47 EventIndex eventIndex = eventHistory.getEventIndex(eventTypes); 48 if (merged == null) { 49 merged = eventIndex; 50 } else if (!eventIndex.isEmpty()) { 51 merged = EventIndex.combine(merged, eventIndex); 52 } 53 } 54 return merged != null ? merged : EventIndex.EMPTY; 55 } 56 57 @NonNull 58 @Override queryEvents(Set<Integer> eventTypes, long startTime, long endTime)59 public List<Event> queryEvents(Set<Integer> eventTypes, long startTime, long endTime) { 60 List<Event> results = new ArrayList<>(); 61 for (EventHistory eventHistory : mEventHistoryList) { 62 EventIndex eventIndex = eventHistory.getEventIndex(eventTypes); 63 if (eventIndex.isEmpty()) { 64 continue; 65 } 66 List<Event> queryResults = eventHistory.queryEvents(eventTypes, startTime, endTime); 67 results = combineEventLists(results, queryResults); 68 } 69 return results; 70 } 71 addEventHistory(EventHistory eventHistory)72 void addEventHistory(EventHistory eventHistory) { 73 mEventHistoryList.add(eventHistory); 74 } 75 76 /** 77 * Combines the sorted events (in chronological order) from the given 2 lists {@code lhs} 78 * and {@code rhs} and preserves the order. 79 */ combineEventLists(List<Event> lhs, List<Event> rhs)80 private List<Event> combineEventLists(List<Event> lhs, List<Event> rhs) { 81 List<Event> results = new ArrayList<>(); 82 int i = 0, j = 0; 83 while (i < lhs.size() && j < rhs.size()) { 84 if (lhs.get(i).getTimestamp() < rhs.get(j).getTimestamp()) { 85 results.add(lhs.get(i++)); 86 } else { 87 results.add(rhs.get(j++)); 88 } 89 } 90 if (i < lhs.size()) { 91 results.addAll(lhs.subList(i, lhs.size())); 92 } else if (j < rhs.size()) { 93 results.addAll(rhs.subList(j, rhs.size())); 94 } 95 return results; 96 } 97 } 98