Loading apex/appsearch/service/java/com/android/server/appsearch/AppSearchConfig.java +72 −0 Original line number Original line Diff line number Diff line Loading @@ -64,6 +64,12 @@ public final class AppSearchConfig implements AutoCloseable { static final int DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES = 512 * 1024; // 512KiB static final int DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES = 512 * 1024; // 512KiB @VisibleForTesting @VisibleForTesting static final int DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_COUNT = 20_000; static final int DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_COUNT = 20_000; @VisibleForTesting static final int DEFAULT_BYTES_OPTIMIZE_THRESHOLD = 1 * 1024 * 1024; // 1 MiB @VisibleForTesting static final int DEFAULT_TIME_OPTIMIZE_THRESHOLD_MILLIS = Integer.MAX_VALUE; @VisibleForTesting static final int DEFAULT_DOC_COUNT_OPTIMIZE_THRESHOLD = 10_000; /* /* * Keys for ALL the flags stored in DeviceConfig. * Keys for ALL the flags stored in DeviceConfig. Loading @@ -79,6 +85,9 @@ public final class AppSearchConfig implements AutoCloseable { "limit_config_max_document_size_bytes"; "limit_config_max_document_size_bytes"; public static final String KEY_LIMIT_CONFIG_MAX_DOCUMENT_COUNT = public static final String KEY_LIMIT_CONFIG_MAX_DOCUMENT_COUNT = "limit_config_max_document_docunt"; "limit_config_max_document_docunt"; public static final String KEY_BYTES_OPTIMIZE_THRESHOLD = "bytes_optimize_threshold"; public static final String KEY_TIME_OPTIMIZE_THRESHOLD_MILLIS = "time_optimize_threshold"; public static final String KEY_DOC_COUNT_OPTIMIZE_THRESHOLD = "doc_count_optimize_threshold"; // Array contains all the corresponding keys for the cached values. // Array contains all the corresponding keys for the cached values. private static final String[] KEYS_TO_ALL_CACHED_VALUES = { private static final String[] KEYS_TO_ALL_CACHED_VALUES = { Loading @@ -88,6 +97,9 @@ public final class AppSearchConfig implements AutoCloseable { KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS, KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS, KEY_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES, KEY_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES, KEY_LIMIT_CONFIG_MAX_DOCUMENT_COUNT, KEY_LIMIT_CONFIG_MAX_DOCUMENT_COUNT, KEY_BYTES_OPTIMIZE_THRESHOLD, KEY_TIME_OPTIMIZE_THRESHOLD_MILLIS, KEY_DOC_COUNT_OPTIMIZE_THRESHOLD }; }; // Lock needed for all the operations in this class. // Lock needed for all the operations in this class. Loading Loading @@ -251,6 +263,48 @@ public final class AppSearchConfig implements AutoCloseable { } } } } /** * Returns the cached optimize byte size threshold. * * An AppSearch Optimize job will be triggered if the bytes size of garbage resource exceeds * this threshold. */ int getCachedBytesOptimizeThreshold() { synchronized (mLock) { throwIfClosedLocked(); return mBundleLocked.getInt(KEY_BYTES_OPTIMIZE_THRESHOLD, DEFAULT_BYTES_OPTIMIZE_THRESHOLD); } } /** * Returns the cached optimize time interval threshold. * * An AppSearch Optimize job will be triggered if the time since last optimize job exceeds * this threshold. */ int getCachedTimeOptimizeThresholdMs() { synchronized (mLock) { throwIfClosedLocked(); return mBundleLocked.getInt(KEY_TIME_OPTIMIZE_THRESHOLD_MILLIS, DEFAULT_TIME_OPTIMIZE_THRESHOLD_MILLIS); } } /** * Returns the cached optimize document count threshold threshold. * * An AppSearch Optimize job will be triggered if the number of document of garbage resource * exceeds this threshold. */ int getCachedDocCountOptimizeThreshold() { synchronized (mLock) { throwIfClosedLocked(); return mBundleLocked.getInt(KEY_DOC_COUNT_OPTIMIZE_THRESHOLD, DEFAULT_DOC_COUNT_OPTIMIZE_THRESHOLD); } } @GuardedBy("mLock") @GuardedBy("mLock") private void throwIfClosedLocked() { private void throwIfClosedLocked() { if (mIsClosedLocked) { if (mIsClosedLocked) { Loading Loading @@ -307,6 +361,24 @@ public final class AppSearchConfig implements AutoCloseable { properties.getInt(key, DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_COUNT)); properties.getInt(key, DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_COUNT)); } } break; break; case KEY_BYTES_OPTIMIZE_THRESHOLD: synchronized (mLock) { mBundleLocked.putInt(key, properties.getInt(key, DEFAULT_BYTES_OPTIMIZE_THRESHOLD)); } break; case KEY_TIME_OPTIMIZE_THRESHOLD_MILLIS: synchronized (mLock) { mBundleLocked.putInt(key, properties.getInt(key, DEFAULT_TIME_OPTIMIZE_THRESHOLD_MILLIS)); } break; case KEY_DOC_COUNT_OPTIMIZE_THRESHOLD: synchronized (mLock) { mBundleLocked.putInt(key, properties.getInt(key, DEFAULT_DOC_COUNT_OPTIMIZE_THRESHOLD)); } break; default: default: break; break; } } Loading apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java +34 −0 Original line number Original line Diff line number Diff line Loading @@ -364,6 +364,12 @@ public class AppSearchManagerService extends SystemService { ++operationSuccessCount; ++operationSuccessCount; invokeCallbackOnResult(callback, invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(setSchemaResponse.getBundle())); AppSearchResult.newSuccessfulResult(setSchemaResponse.getBundle())); // setSchema will sync the schemas in the request to AppSearch, any existing // schemas which is not included in the request will be delete if we force // override incompatible schemas. And all documents of these types will be // deleted as well. We should checkForOptimize for these deletion. checkForOptimize(instance); } catch (Throwable t) { } catch (Throwable t) { ++operationFailureCount; ++operationFailureCount; statusCode = throwableToFailedResult(t).getResultCode(); statusCode = throwableToFailedResult(t).getResultCode(); Loading Loading @@ -505,6 +511,10 @@ public class AppSearchManagerService extends SystemService { // Now that the batch has been written. Persist the newly written data. // Now that the batch has been written. Persist the newly written data. instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE); instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE); invokeCallbackOnResult(callback, resultBuilder.build()); invokeCallbackOnResult(callback, resultBuilder.build()); // The existing documents with same ID will be deleted, so there may be some // resources that could be released after optimize(). checkForOptimize(instance, /*mutateBatchSize=*/ documentBundles.size()); } catch (Throwable t) { } catch (Throwable t) { ++operationFailureCount; ++operationFailureCount; statusCode = throwableToFailedResult(t).getResultCode(); statusCode = throwableToFailedResult(t).getResultCode(); Loading Loading @@ -1023,6 +1033,8 @@ public class AppSearchManagerService extends SystemService { // Now that the batch has been written. Persist the newly written data. // Now that the batch has been written. Persist the newly written data. instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE); instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE); invokeCallbackOnResult(callback, resultBuilder.build()); invokeCallbackOnResult(callback, resultBuilder.build()); checkForOptimize(instance, ids.size()); } catch (Throwable t) { } catch (Throwable t) { ++operationFailureCount; ++operationFailureCount; statusCode = throwableToFailedResult(t).getResultCode(); statusCode = throwableToFailedResult(t).getResultCode(); Loading Loading @@ -1092,6 +1104,8 @@ public class AppSearchManagerService extends SystemService { instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE); instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE); ++operationSuccessCount; ++operationSuccessCount; invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null)); invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null)); checkForOptimize(instance); } catch (Throwable t) { } catch (Throwable t) { ++operationFailureCount; ++operationFailureCount; statusCode = throwableToFailedResult(t).getResultCode(); statusCode = throwableToFailedResult(t).getResultCode(); Loading Loading @@ -1472,4 +1486,24 @@ public class AppSearchManagerService extends SystemService { } } } } } } private void checkForOptimize(AppSearchUserInstance instance, int mutateBatchSize) { EXECUTOR.execute(() -> { try { instance.getAppSearchImpl().checkForOptimize(mutateBatchSize); } catch (AppSearchException e) { Log.w(TAG, "Error occurred when check for optimize", e); } }); } private void checkForOptimize(AppSearchUserInstance instance) { EXECUTOR.execute(() -> { try { instance.getAppSearchImpl().checkForOptimize(); } catch (AppSearchException e) { Log.w(TAG, "Error occurred when check for optimize", e); } }); } } } apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstanceManager.java +1 −2 Original line number Original line Diff line number Diff line Loading @@ -27,7 +27,6 @@ import android.util.Log; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy; import com.android.server.appsearch.external.localstorage.AppSearchImpl; import com.android.server.appsearch.external.localstorage.AppSearchImpl; import com.android.server.appsearch.external.localstorage.FrameworkOptimizeStrategy; import com.android.server.appsearch.external.localstorage.stats.InitializeStats; import com.android.server.appsearch.external.localstorage.stats.InitializeStats; import com.android.server.appsearch.stats.PlatformLogger; import com.android.server.appsearch.stats.PlatformLogger; import com.android.server.appsearch.visibilitystore.VisibilityStoreImpl; import com.android.server.appsearch.visibilitystore.VisibilityStoreImpl; Loading Loading @@ -177,7 +176,7 @@ public final class AppSearchUserInstanceManager { icingDir, icingDir, new FrameworkLimitConfig(config), new FrameworkLimitConfig(config), initStatsBuilder, initStatsBuilder, new FrameworkOptimizeStrategy()); new FrameworkOptimizeStrategy(config)); long prepareVisibilityStoreLatencyStartMillis = SystemClock.elapsedRealtime(); long prepareVisibilityStoreLatencyStartMillis = SystemClock.elapsedRealtime(); VisibilityStoreImpl visibilityStore = VisibilityStoreImpl visibilityStore = Loading apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/FrameworkOptimizeStrategy.java→apex/appsearch/service/java/com/android/server/appsearch/FrameworkOptimizeStrategy.java +16 −12 Original line number Original line Diff line number Diff line /* /* * Copyright 2021 The Android Open Source Project * Copyright (C) 2021 The Android Open Source Project * * * Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License. Loading @@ -13,14 +13,17 @@ * See the License for the specific language governing permissions and * See the License for the specific language governing permissions and * limitations under the License. * limitations under the License. */ */ package com.android.server.appsearch.external.localstorage; package com.android.server.appsearch; import android.annotation.NonNull; import android.annotation.NonNull; import com.android.internal.annotations.VisibleForTesting; import com.android.server.appsearch.external.localstorage.AppSearchImpl; import com.android.server.appsearch.external.localstorage.OptimizeStrategy; import com.google.android.icing.proto.GetOptimizeInfoResultProto; import com.google.android.icing.proto.GetOptimizeInfoResultProto; import java.util.Objects; /** /** * An implementation of {@link OptimizeStrategy} will determine when to trigger {@link * An implementation of {@link OptimizeStrategy} will determine when to trigger {@link * AppSearchImpl#optimize()} in Jetpack environment. * AppSearchImpl#optimize()} in Jetpack environment. Loading @@ -28,17 +31,18 @@ import com.google.android.icing.proto.GetOptimizeInfoResultProto; * @hide * @hide */ */ public class FrameworkOptimizeStrategy implements OptimizeStrategy { public class FrameworkOptimizeStrategy implements OptimizeStrategy { private final AppSearchConfig mAppSearchConfig; @VisibleForTesting static final int DOC_COUNT_OPTIMIZE_THRESHOLD = 100_000; FrameworkOptimizeStrategy(@NonNull AppSearchConfig config) { @VisibleForTesting static final int BYTES_OPTIMIZE_THRESHOLD = 1 * 1024 * 1024 * 1024; // 1GB mAppSearchConfig = Objects.requireNonNull(config); } @VisibleForTesting static final long TIME_OPTIMIZE_THRESHOLD_MILLIS = 7 * 24 * 60 * 60 * 1000; // 1 week @Override @Override public boolean shouldOptimize(@NonNull GetOptimizeInfoResultProto optimizeInfo) { public boolean shouldOptimize(@NonNull GetOptimizeInfoResultProto optimizeInfo) { return optimizeInfo.getOptimizableDocs() >= DOC_COUNT_OPTIMIZE_THRESHOLD return optimizeInfo.getOptimizableDocs() || optimizeInfo.getEstimatedOptimizableBytes() >= BYTES_OPTIMIZE_THRESHOLD >= mAppSearchConfig.getCachedDocCountOptimizeThreshold() || optimizeInfo.getTimeSinceLastOptimizeMs() >= TIME_OPTIMIZE_THRESHOLD_MILLIS; || optimizeInfo.getEstimatedOptimizableBytes() >= mAppSearchConfig.getCachedBytesOptimizeThreshold() || optimizeInfo.getTimeSinceLastOptimizeMs() >= mAppSearchConfig.getCachedTimeOptimizeThresholdMs(); } } } } apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java +4 −4 Original line number Original line Diff line number Diff line Loading @@ -203,7 +203,7 @@ public final class PlatformLogger implements AppSearchLogger { stats.getNumOperationsSucceeded(), stats.getNumOperationsSucceeded(), stats.getNumOperationsFailed()); stats.getNumOperationsFailed()); } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { // TODO(b/184204720) report hashing error to Westworld // TODO(b/184204720) report hashing error to statsd // We need to set a special value(e.g. 0xFFFFFFFF) for the hashing of the database, // We need to set a special value(e.g. 0xFFFFFFFF) for the hashing of the database, // so in the dashboard we know there is some error for hashing. // so in the dashboard we know there is some error for hashing. // // Loading Loading @@ -240,7 +240,7 @@ public final class PlatformLogger implements AppSearchLogger { stats.getNativeNumTokensIndexed(), stats.getNativeNumTokensIndexed(), stats.getNativeExceededMaxNumTokens()); stats.getNativeExceededMaxNumTokens()); } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { // TODO(b/184204720) report hashing error to Westworld // TODO(b/184204720) report hashing error to statsd // We need to set a special value(e.g. 0xFFFFFFFF) for the hashing of the database, // We need to set a special value(e.g. 0xFFFFFFFF) for the hashing of the database, // so in the dashboard we know there is some error for hashing. // so in the dashboard we know there is some error for hashing. // // Loading Loading @@ -286,7 +286,7 @@ public final class PlatformLogger implements AppSearchLogger { stats.getDocumentRetrievingLatencyMillis(), stats.getDocumentRetrievingLatencyMillis(), stats.getResultWithSnippetsCount()); stats.getResultWithSnippetsCount()); } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { // TODO(b/184204720) report hashing error to Westworld // TODO(b/184204720) report hashing error to statsd // We need to set a special value(e.g. 0xFFFFFFFF) for the hashing of the database, // We need to set a special value(e.g. 0xFFFFFFFF) for the hashing of the database, // so in the dashboard we know there is some error for hashing. // so in the dashboard we know there is some error for hashing. // // Loading Loading @@ -363,7 +363,7 @@ public final class PlatformLogger implements AppSearchLogger { /** /** * Creates {@link ExtraStats} to hold additional information generated for logging. * Creates {@link ExtraStats} to hold additional information generated for logging. * * * <p>This method is called by most of logToWestworldLocked functions to reduce code * <p>This method is called by most of logStatsImplLocked functions to reduce code * duplication. * duplication. */ */ // TODO(b/173532925) Once we add CTS test for logging atoms and can inspect the result, we can // TODO(b/173532925) Once we add CTS test for logging atoms and can inspect the result, we can Loading Loading
apex/appsearch/service/java/com/android/server/appsearch/AppSearchConfig.java +72 −0 Original line number Original line Diff line number Diff line Loading @@ -64,6 +64,12 @@ public final class AppSearchConfig implements AutoCloseable { static final int DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES = 512 * 1024; // 512KiB static final int DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES = 512 * 1024; // 512KiB @VisibleForTesting @VisibleForTesting static final int DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_COUNT = 20_000; static final int DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_COUNT = 20_000; @VisibleForTesting static final int DEFAULT_BYTES_OPTIMIZE_THRESHOLD = 1 * 1024 * 1024; // 1 MiB @VisibleForTesting static final int DEFAULT_TIME_OPTIMIZE_THRESHOLD_MILLIS = Integer.MAX_VALUE; @VisibleForTesting static final int DEFAULT_DOC_COUNT_OPTIMIZE_THRESHOLD = 10_000; /* /* * Keys for ALL the flags stored in DeviceConfig. * Keys for ALL the flags stored in DeviceConfig. Loading @@ -79,6 +85,9 @@ public final class AppSearchConfig implements AutoCloseable { "limit_config_max_document_size_bytes"; "limit_config_max_document_size_bytes"; public static final String KEY_LIMIT_CONFIG_MAX_DOCUMENT_COUNT = public static final String KEY_LIMIT_CONFIG_MAX_DOCUMENT_COUNT = "limit_config_max_document_docunt"; "limit_config_max_document_docunt"; public static final String KEY_BYTES_OPTIMIZE_THRESHOLD = "bytes_optimize_threshold"; public static final String KEY_TIME_OPTIMIZE_THRESHOLD_MILLIS = "time_optimize_threshold"; public static final String KEY_DOC_COUNT_OPTIMIZE_THRESHOLD = "doc_count_optimize_threshold"; // Array contains all the corresponding keys for the cached values. // Array contains all the corresponding keys for the cached values. private static final String[] KEYS_TO_ALL_CACHED_VALUES = { private static final String[] KEYS_TO_ALL_CACHED_VALUES = { Loading @@ -88,6 +97,9 @@ public final class AppSearchConfig implements AutoCloseable { KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS, KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS, KEY_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES, KEY_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES, KEY_LIMIT_CONFIG_MAX_DOCUMENT_COUNT, KEY_LIMIT_CONFIG_MAX_DOCUMENT_COUNT, KEY_BYTES_OPTIMIZE_THRESHOLD, KEY_TIME_OPTIMIZE_THRESHOLD_MILLIS, KEY_DOC_COUNT_OPTIMIZE_THRESHOLD }; }; // Lock needed for all the operations in this class. // Lock needed for all the operations in this class. Loading Loading @@ -251,6 +263,48 @@ public final class AppSearchConfig implements AutoCloseable { } } } } /** * Returns the cached optimize byte size threshold. * * An AppSearch Optimize job will be triggered if the bytes size of garbage resource exceeds * this threshold. */ int getCachedBytesOptimizeThreshold() { synchronized (mLock) { throwIfClosedLocked(); return mBundleLocked.getInt(KEY_BYTES_OPTIMIZE_THRESHOLD, DEFAULT_BYTES_OPTIMIZE_THRESHOLD); } } /** * Returns the cached optimize time interval threshold. * * An AppSearch Optimize job will be triggered if the time since last optimize job exceeds * this threshold. */ int getCachedTimeOptimizeThresholdMs() { synchronized (mLock) { throwIfClosedLocked(); return mBundleLocked.getInt(KEY_TIME_OPTIMIZE_THRESHOLD_MILLIS, DEFAULT_TIME_OPTIMIZE_THRESHOLD_MILLIS); } } /** * Returns the cached optimize document count threshold threshold. * * An AppSearch Optimize job will be triggered if the number of document of garbage resource * exceeds this threshold. */ int getCachedDocCountOptimizeThreshold() { synchronized (mLock) { throwIfClosedLocked(); return mBundleLocked.getInt(KEY_DOC_COUNT_OPTIMIZE_THRESHOLD, DEFAULT_DOC_COUNT_OPTIMIZE_THRESHOLD); } } @GuardedBy("mLock") @GuardedBy("mLock") private void throwIfClosedLocked() { private void throwIfClosedLocked() { if (mIsClosedLocked) { if (mIsClosedLocked) { Loading Loading @@ -307,6 +361,24 @@ public final class AppSearchConfig implements AutoCloseable { properties.getInt(key, DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_COUNT)); properties.getInt(key, DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_COUNT)); } } break; break; case KEY_BYTES_OPTIMIZE_THRESHOLD: synchronized (mLock) { mBundleLocked.putInt(key, properties.getInt(key, DEFAULT_BYTES_OPTIMIZE_THRESHOLD)); } break; case KEY_TIME_OPTIMIZE_THRESHOLD_MILLIS: synchronized (mLock) { mBundleLocked.putInt(key, properties.getInt(key, DEFAULT_TIME_OPTIMIZE_THRESHOLD_MILLIS)); } break; case KEY_DOC_COUNT_OPTIMIZE_THRESHOLD: synchronized (mLock) { mBundleLocked.putInt(key, properties.getInt(key, DEFAULT_DOC_COUNT_OPTIMIZE_THRESHOLD)); } break; default: default: break; break; } } Loading
apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java +34 −0 Original line number Original line Diff line number Diff line Loading @@ -364,6 +364,12 @@ public class AppSearchManagerService extends SystemService { ++operationSuccessCount; ++operationSuccessCount; invokeCallbackOnResult(callback, invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(setSchemaResponse.getBundle())); AppSearchResult.newSuccessfulResult(setSchemaResponse.getBundle())); // setSchema will sync the schemas in the request to AppSearch, any existing // schemas which is not included in the request will be delete if we force // override incompatible schemas. And all documents of these types will be // deleted as well. We should checkForOptimize for these deletion. checkForOptimize(instance); } catch (Throwable t) { } catch (Throwable t) { ++operationFailureCount; ++operationFailureCount; statusCode = throwableToFailedResult(t).getResultCode(); statusCode = throwableToFailedResult(t).getResultCode(); Loading Loading @@ -505,6 +511,10 @@ public class AppSearchManagerService extends SystemService { // Now that the batch has been written. Persist the newly written data. // Now that the batch has been written. Persist the newly written data. instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE); instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE); invokeCallbackOnResult(callback, resultBuilder.build()); invokeCallbackOnResult(callback, resultBuilder.build()); // The existing documents with same ID will be deleted, so there may be some // resources that could be released after optimize(). checkForOptimize(instance, /*mutateBatchSize=*/ documentBundles.size()); } catch (Throwable t) { } catch (Throwable t) { ++operationFailureCount; ++operationFailureCount; statusCode = throwableToFailedResult(t).getResultCode(); statusCode = throwableToFailedResult(t).getResultCode(); Loading Loading @@ -1023,6 +1033,8 @@ public class AppSearchManagerService extends SystemService { // Now that the batch has been written. Persist the newly written data. // Now that the batch has been written. Persist the newly written data. instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE); instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE); invokeCallbackOnResult(callback, resultBuilder.build()); invokeCallbackOnResult(callback, resultBuilder.build()); checkForOptimize(instance, ids.size()); } catch (Throwable t) { } catch (Throwable t) { ++operationFailureCount; ++operationFailureCount; statusCode = throwableToFailedResult(t).getResultCode(); statusCode = throwableToFailedResult(t).getResultCode(); Loading Loading @@ -1092,6 +1104,8 @@ public class AppSearchManagerService extends SystemService { instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE); instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE); ++operationSuccessCount; ++operationSuccessCount; invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null)); invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null)); checkForOptimize(instance); } catch (Throwable t) { } catch (Throwable t) { ++operationFailureCount; ++operationFailureCount; statusCode = throwableToFailedResult(t).getResultCode(); statusCode = throwableToFailedResult(t).getResultCode(); Loading Loading @@ -1472,4 +1486,24 @@ public class AppSearchManagerService extends SystemService { } } } } } } private void checkForOptimize(AppSearchUserInstance instance, int mutateBatchSize) { EXECUTOR.execute(() -> { try { instance.getAppSearchImpl().checkForOptimize(mutateBatchSize); } catch (AppSearchException e) { Log.w(TAG, "Error occurred when check for optimize", e); } }); } private void checkForOptimize(AppSearchUserInstance instance) { EXECUTOR.execute(() -> { try { instance.getAppSearchImpl().checkForOptimize(); } catch (AppSearchException e) { Log.w(TAG, "Error occurred when check for optimize", e); } }); } } }
apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstanceManager.java +1 −2 Original line number Original line Diff line number Diff line Loading @@ -27,7 +27,6 @@ import android.util.Log; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy; import com.android.server.appsearch.external.localstorage.AppSearchImpl; import com.android.server.appsearch.external.localstorage.AppSearchImpl; import com.android.server.appsearch.external.localstorage.FrameworkOptimizeStrategy; import com.android.server.appsearch.external.localstorage.stats.InitializeStats; import com.android.server.appsearch.external.localstorage.stats.InitializeStats; import com.android.server.appsearch.stats.PlatformLogger; import com.android.server.appsearch.stats.PlatformLogger; import com.android.server.appsearch.visibilitystore.VisibilityStoreImpl; import com.android.server.appsearch.visibilitystore.VisibilityStoreImpl; Loading Loading @@ -177,7 +176,7 @@ public final class AppSearchUserInstanceManager { icingDir, icingDir, new FrameworkLimitConfig(config), new FrameworkLimitConfig(config), initStatsBuilder, initStatsBuilder, new FrameworkOptimizeStrategy()); new FrameworkOptimizeStrategy(config)); long prepareVisibilityStoreLatencyStartMillis = SystemClock.elapsedRealtime(); long prepareVisibilityStoreLatencyStartMillis = SystemClock.elapsedRealtime(); VisibilityStoreImpl visibilityStore = VisibilityStoreImpl visibilityStore = Loading
apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/FrameworkOptimizeStrategy.java→apex/appsearch/service/java/com/android/server/appsearch/FrameworkOptimizeStrategy.java +16 −12 Original line number Original line Diff line number Diff line /* /* * Copyright 2021 The Android Open Source Project * Copyright (C) 2021 The Android Open Source Project * * * Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License. Loading @@ -13,14 +13,17 @@ * See the License for the specific language governing permissions and * See the License for the specific language governing permissions and * limitations under the License. * limitations under the License. */ */ package com.android.server.appsearch.external.localstorage; package com.android.server.appsearch; import android.annotation.NonNull; import android.annotation.NonNull; import com.android.internal.annotations.VisibleForTesting; import com.android.server.appsearch.external.localstorage.AppSearchImpl; import com.android.server.appsearch.external.localstorage.OptimizeStrategy; import com.google.android.icing.proto.GetOptimizeInfoResultProto; import com.google.android.icing.proto.GetOptimizeInfoResultProto; import java.util.Objects; /** /** * An implementation of {@link OptimizeStrategy} will determine when to trigger {@link * An implementation of {@link OptimizeStrategy} will determine when to trigger {@link * AppSearchImpl#optimize()} in Jetpack environment. * AppSearchImpl#optimize()} in Jetpack environment. Loading @@ -28,17 +31,18 @@ import com.google.android.icing.proto.GetOptimizeInfoResultProto; * @hide * @hide */ */ public class FrameworkOptimizeStrategy implements OptimizeStrategy { public class FrameworkOptimizeStrategy implements OptimizeStrategy { private final AppSearchConfig mAppSearchConfig; @VisibleForTesting static final int DOC_COUNT_OPTIMIZE_THRESHOLD = 100_000; FrameworkOptimizeStrategy(@NonNull AppSearchConfig config) { @VisibleForTesting static final int BYTES_OPTIMIZE_THRESHOLD = 1 * 1024 * 1024 * 1024; // 1GB mAppSearchConfig = Objects.requireNonNull(config); } @VisibleForTesting static final long TIME_OPTIMIZE_THRESHOLD_MILLIS = 7 * 24 * 60 * 60 * 1000; // 1 week @Override @Override public boolean shouldOptimize(@NonNull GetOptimizeInfoResultProto optimizeInfo) { public boolean shouldOptimize(@NonNull GetOptimizeInfoResultProto optimizeInfo) { return optimizeInfo.getOptimizableDocs() >= DOC_COUNT_OPTIMIZE_THRESHOLD return optimizeInfo.getOptimizableDocs() || optimizeInfo.getEstimatedOptimizableBytes() >= BYTES_OPTIMIZE_THRESHOLD >= mAppSearchConfig.getCachedDocCountOptimizeThreshold() || optimizeInfo.getTimeSinceLastOptimizeMs() >= TIME_OPTIMIZE_THRESHOLD_MILLIS; || optimizeInfo.getEstimatedOptimizableBytes() >= mAppSearchConfig.getCachedBytesOptimizeThreshold() || optimizeInfo.getTimeSinceLastOptimizeMs() >= mAppSearchConfig.getCachedTimeOptimizeThresholdMs(); } } } }
apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java +4 −4 Original line number Original line Diff line number Diff line Loading @@ -203,7 +203,7 @@ public final class PlatformLogger implements AppSearchLogger { stats.getNumOperationsSucceeded(), stats.getNumOperationsSucceeded(), stats.getNumOperationsFailed()); stats.getNumOperationsFailed()); } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { // TODO(b/184204720) report hashing error to Westworld // TODO(b/184204720) report hashing error to statsd // We need to set a special value(e.g. 0xFFFFFFFF) for the hashing of the database, // We need to set a special value(e.g. 0xFFFFFFFF) for the hashing of the database, // so in the dashboard we know there is some error for hashing. // so in the dashboard we know there is some error for hashing. // // Loading Loading @@ -240,7 +240,7 @@ public final class PlatformLogger implements AppSearchLogger { stats.getNativeNumTokensIndexed(), stats.getNativeNumTokensIndexed(), stats.getNativeExceededMaxNumTokens()); stats.getNativeExceededMaxNumTokens()); } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { // TODO(b/184204720) report hashing error to Westworld // TODO(b/184204720) report hashing error to statsd // We need to set a special value(e.g. 0xFFFFFFFF) for the hashing of the database, // We need to set a special value(e.g. 0xFFFFFFFF) for the hashing of the database, // so in the dashboard we know there is some error for hashing. // so in the dashboard we know there is some error for hashing. // // Loading Loading @@ -286,7 +286,7 @@ public final class PlatformLogger implements AppSearchLogger { stats.getDocumentRetrievingLatencyMillis(), stats.getDocumentRetrievingLatencyMillis(), stats.getResultWithSnippetsCount()); stats.getResultWithSnippetsCount()); } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { // TODO(b/184204720) report hashing error to Westworld // TODO(b/184204720) report hashing error to statsd // We need to set a special value(e.g. 0xFFFFFFFF) for the hashing of the database, // We need to set a special value(e.g. 0xFFFFFFFF) for the hashing of the database, // so in the dashboard we know there is some error for hashing. // so in the dashboard we know there is some error for hashing. // // Loading Loading @@ -363,7 +363,7 @@ public final class PlatformLogger implements AppSearchLogger { /** /** * Creates {@link ExtraStats} to hold additional information generated for logging. * Creates {@link ExtraStats} to hold additional information generated for logging. * * * <p>This method is called by most of logToWestworldLocked functions to reduce code * <p>This method is called by most of logStatsImplLocked functions to reduce code * duplication. * duplication. */ */ // TODO(b/173532925) Once we add CTS test for logging atoms and can inspect the result, we can // TODO(b/173532925) Once we add CTS test for logging atoms and can inspect the result, we can Loading