1 /*
2  * Copyright (C) 2021 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 package com.android.server.appsearch;
17 
18 import android.annotation.NonNull;
19 import android.app.appsearch.util.LogUtil;
20 import android.util.Log;
21 
22 import com.android.server.appsearch.external.localstorage.AppSearchImpl;
23 import com.android.server.appsearch.external.localstorage.OptimizeStrategy;
24 
25 import com.google.android.icing.proto.GetOptimizeInfoResultProto;
26 
27 import java.util.Objects;
28 
29 /**
30  * An implementation of {@link OptimizeStrategy} will determine when to trigger {@link
31  * AppSearchImpl#optimize()} based on last time optimize ran and number of bytes to optimize. This
32  * implementation is used by environments with AppSearch service running like Framework and GMSCore.
33  *
34  * @hide
35  */
36 public class ServiceOptimizeStrategy implements OptimizeStrategy {
37     private static final String TAG = "AppSearchOptimize";
38     private final ServiceAppSearchConfig mAppSearchConfig;
39 
ServiceOptimizeStrategy(@onNull ServiceAppSearchConfig config)40     ServiceOptimizeStrategy(@NonNull ServiceAppSearchConfig config) {
41         mAppSearchConfig = Objects.requireNonNull(config);
42     }
43 
44     @Override
shouldOptimize(@onNull GetOptimizeInfoResultProto optimizeInfo)45     public boolean shouldOptimize(@NonNull GetOptimizeInfoResultProto optimizeInfo) {
46         boolean wantsOptimize =
47                 optimizeInfo.getOptimizableDocs()
48                                 >= mAppSearchConfig.getCachedDocCountOptimizeThreshold()
49                         || optimizeInfo.getEstimatedOptimizableBytes()
50                                 >= mAppSearchConfig.getCachedBytesOptimizeThreshold()
51                         || optimizeInfo.getTimeSinceLastOptimizeMs()
52                                 >= mAppSearchConfig.getCachedTimeOptimizeThresholdMs();
53         if (wantsOptimize
54                 && optimizeInfo.getTimeSinceLastOptimizeMs()
55                         < mAppSearchConfig.getCachedMinTimeOptimizeThresholdMs()) {
56             // TODO(b/271890504): Produce a log message for statsd when we skip a potential
57             //  compaction because the time since the last compaction has not reached
58             //  the minimum threshold.
59             if (LogUtil.INFO) {
60                 Log.i(
61                         TAG,
62                         "Skipping optimization because time since last optimize ["
63                                 + optimizeInfo.getTimeSinceLastOptimizeMs()
64                                 + " ms] is lesser than the threshold for minimum time between"
65                                 + " optimizations ["
66                                 + mAppSearchConfig.getCachedMinTimeOptimizeThresholdMs()
67                                 + " ms]");
68             }
69             return false;
70         }
71         return wantsOptimize;
72     }
73 }
74