1 /* 2 * Copyright 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 17 package com.android.server.appsearch.external.localstorage.stats; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.app.appsearch.AppSearchResult; 22 23 import java.lang.annotation.Retention; 24 import java.lang.annotation.RetentionPolicy; 25 import java.util.Objects; 26 27 /** 28 * Class holds detailed stats for initialization 29 * 30 * @hide 31 */ 32 public final class InitializeStats { 33 /** 34 * The cause of IcingSearchEngine recovering from a previous bad state during initialization. 35 */ 36 @IntDef( 37 value = { 38 // It needs to be sync with RecoveryCause in 39 // external/icing/proto/icing/proto/logging.proto#InitializeStatsProto 40 RECOVERY_CAUSE_NONE, 41 RECOVERY_CAUSE_DATA_LOSS, 42 RECOVERY_CAUSE_INCONSISTENT_WITH_GROUND_TRUTH, 43 RECOVERY_CAUSE_TOTAL_CHECKSUM_MISMATCH, 44 RECOVERY_CAUSE_IO_ERROR, 45 }) 46 @Retention(RetentionPolicy.SOURCE) 47 public @interface RecoveryCause {} 48 49 // No recovery happened. 50 public static final int RECOVERY_CAUSE_NONE = 0; 51 // Data loss in ground truth. 52 public static final int RECOVERY_CAUSE_DATA_LOSS = 1; 53 // Data in index is inconsistent with ground truth. 54 public static final int RECOVERY_CAUSE_INCONSISTENT_WITH_GROUND_TRUTH = 2; 55 // Total checksum of all the components does not match. 56 public static final int RECOVERY_CAUSE_TOTAL_CHECKSUM_MISMATCH = 3; 57 // Random I/O errors. 58 public static final int RECOVERY_CAUSE_IO_ERROR = 4; 59 60 /** Status regarding how much data is lost during the initialization. */ 61 @IntDef( 62 value = { 63 // It needs to be sync with DocumentStoreDataStatus in 64 // external/icing/proto/icing/proto/logging.proto#InitializeStatsProto 65 66 DOCUMENT_STORE_DATA_STATUS_NO_DATA_LOSS, 67 DOCUMENT_STORE_DATA_STATUS_PARTIAL_LOSS, 68 DOCUMENT_STORE_DATA_STATUS_COMPLETE_LOSS, 69 }) 70 @Retention(RetentionPolicy.SOURCE) 71 public @interface DocumentStoreDataStatus {} 72 73 // Document store is successfully initialized or fully recovered. 74 public static final int DOCUMENT_STORE_DATA_STATUS_NO_DATA_LOSS = 0; 75 // Ground truth data is partially lost. 76 public static final int DOCUMENT_STORE_DATA_STATUS_PARTIAL_LOSS = 1; 77 // Ground truth data is completely lost. 78 public static final int DOCUMENT_STORE_DATA_STATUS_COMPLETE_LOSS = 2; 79 80 @AppSearchResult.ResultCode private final int mStatusCode; 81 private final int mTotalLatencyMillis; 82 /** Whether the initialize() detects deSync. */ 83 private final boolean mHasDeSync; 84 /** Time used to read and process the schema and namespaces. */ 85 private final int mPrepareSchemaAndNamespacesLatencyMillis; 86 /** Time used to read and process the visibility store. */ 87 private final int mPrepareVisibilityStoreLatencyMillis; 88 /** Overall time used for the native function call. */ 89 private final int mNativeLatencyMillis; 90 91 @RecoveryCause private final int mNativeDocumentStoreRecoveryCause; 92 @RecoveryCause private final int mNativeIndexRestorationCause; 93 @RecoveryCause private final int mNativeSchemaStoreRecoveryCause; 94 /** Time used to recover the document store. */ 95 private final int mNativeDocumentStoreRecoveryLatencyMillis; 96 /** Time used to restore the index. */ 97 private final int mNativeIndexRestorationLatencyMillis; 98 /** Time used to recover the schema store. */ 99 private final int mNativeSchemaStoreRecoveryLatencyMillis; 100 /** Status regarding how much data is lost during the initialization. */ 101 private final int mNativeDocumentStoreDataStatus; 102 /** 103 * Returns number of documents currently in document store. Those may include alive, deleted, 104 * and expired documents. 105 */ 106 private final int mNativeNumDocuments; 107 /** Returns number of schema types currently in the schema store. */ 108 private final int mNativeNumSchemaTypes; 109 /** Whether we had to reset the index, losing all data, during initialization. */ 110 private final boolean mHasReset; 111 /** If we had to reset, contains the status code of the reset operation. */ 112 @AppSearchResult.ResultCode private final int mResetStatusCode; 113 114 /** Returns the status of the initialization. */ 115 @AppSearchResult.ResultCode getStatusCode()116 public int getStatusCode() { 117 return mStatusCode; 118 } 119 120 /** Returns the total latency in milliseconds for the initialization. */ getTotalLatencyMillis()121 public int getTotalLatencyMillis() { 122 return mTotalLatencyMillis; 123 } 124 125 /** 126 * Returns whether the initialize() detects deSync. 127 * 128 * <p>If there is a deSync, it means AppSearch and IcingSearchEngine have an inconsistent view 129 * of what data should exist. 130 */ hasDeSync()131 public boolean hasDeSync() { 132 return mHasDeSync; 133 } 134 135 /** Returns time used to read and process the schema and namespaces. */ getPrepareSchemaAndNamespacesLatencyMillis()136 public int getPrepareSchemaAndNamespacesLatencyMillis() { 137 return mPrepareSchemaAndNamespacesLatencyMillis; 138 } 139 140 /** Returns time used to read and process the visibility file. */ getPrepareVisibilityStoreLatencyMillis()141 public int getPrepareVisibilityStoreLatencyMillis() { 142 return mPrepareVisibilityStoreLatencyMillis; 143 } 144 145 /** Returns overall time used for the native function call. */ getNativeLatencyMillis()146 public int getNativeLatencyMillis() { 147 return mNativeLatencyMillis; 148 } 149 150 /** 151 * Returns recovery cause for document store. 152 * 153 * <p>Possible recovery causes for document store: 154 * <li>{@link InitializeStats#RECOVERY_CAUSE_DATA_LOSS} 155 * <li>{@link InitializeStats#RECOVERY_CAUSE_TOTAL_CHECKSUM_MISMATCH} 156 * <li>{@link InitializeStats#RECOVERY_CAUSE_IO_ERROR} 157 */ 158 @RecoveryCause getDocumentStoreRecoveryCause()159 public int getDocumentStoreRecoveryCause() { 160 return mNativeDocumentStoreRecoveryCause; 161 } 162 163 /** 164 * Returns restoration cause for index store. 165 * 166 * <p>Possible causes: 167 * <li>{@link InitializeStats#RECOVERY_CAUSE_INCONSISTENT_WITH_GROUND_TRUTH} 168 * <li>{@link InitializeStats#RECOVERY_CAUSE_TOTAL_CHECKSUM_MISMATCH} 169 * <li>{@link InitializeStats#RECOVERY_CAUSE_IO_ERROR} 170 */ 171 @RecoveryCause getIndexRestorationCause()172 public int getIndexRestorationCause() { 173 return mNativeIndexRestorationCause; 174 } 175 176 /** 177 * Returns recovery cause for schema store. 178 * 179 * <p>Possible causes: 180 * <li>IO_ERROR 181 */ 182 @RecoveryCause getSchemaStoreRecoveryCause()183 public int getSchemaStoreRecoveryCause() { 184 return mNativeSchemaStoreRecoveryCause; 185 } 186 187 /** Returns time used to recover the document store. */ getDocumentStoreRecoveryLatencyMillis()188 public int getDocumentStoreRecoveryLatencyMillis() { 189 return mNativeDocumentStoreRecoveryLatencyMillis; 190 } 191 192 /** Returns time used to restore the index. */ getIndexRestorationLatencyMillis()193 public int getIndexRestorationLatencyMillis() { 194 return mNativeIndexRestorationLatencyMillis; 195 } 196 197 /** Returns time used to recover the schema store. */ getSchemaStoreRecoveryLatencyMillis()198 public int getSchemaStoreRecoveryLatencyMillis() { 199 return mNativeSchemaStoreRecoveryLatencyMillis; 200 } 201 202 /** Returns status about how much data is lost during the initialization. */ 203 @DocumentStoreDataStatus getDocumentStoreDataStatus()204 public int getDocumentStoreDataStatus() { 205 return mNativeDocumentStoreDataStatus; 206 } 207 208 /** 209 * Returns number of documents currently in document store. Those may include alive, deleted, 210 * and expired documents. 211 */ getDocumentCount()212 public int getDocumentCount() { 213 return mNativeNumDocuments; 214 } 215 216 /** Returns number of schema types currently in the schema store. */ getSchemaTypeCount()217 public int getSchemaTypeCount() { 218 return mNativeNumSchemaTypes; 219 } 220 221 /** Returns whether we had to reset the index, losing all data, as part of initialization. */ hasReset()222 public boolean hasReset() { 223 return mHasReset; 224 } 225 226 /** 227 * Returns the status of the reset, if one was performed according to {@link #hasReset}. 228 * 229 * <p>If no value has been set, the default value is {@link AppSearchResult#RESULT_OK}. 230 */ 231 @AppSearchResult.ResultCode getResetStatusCode()232 public int getResetStatusCode() { 233 return mResetStatusCode; 234 } 235 InitializeStats(@onNull Builder builder)236 InitializeStats(@NonNull Builder builder) { 237 Objects.requireNonNull(builder); 238 mStatusCode = builder.mStatusCode; 239 mTotalLatencyMillis = builder.mTotalLatencyMillis; 240 mHasDeSync = builder.mHasDeSync; 241 mPrepareSchemaAndNamespacesLatencyMillis = builder.mPrepareSchemaAndNamespacesLatencyMillis; 242 mPrepareVisibilityStoreLatencyMillis = builder.mPrepareVisibilityStoreLatencyMillis; 243 mNativeLatencyMillis = builder.mNativeLatencyMillis; 244 mNativeDocumentStoreRecoveryCause = builder.mNativeDocumentStoreRecoveryCause; 245 mNativeIndexRestorationCause = builder.mNativeIndexRestorationCause; 246 mNativeSchemaStoreRecoveryCause = builder.mNativeSchemaStoreRecoveryCause; 247 mNativeDocumentStoreRecoveryLatencyMillis = 248 builder.mNativeDocumentStoreRecoveryLatencyMillis; 249 mNativeIndexRestorationLatencyMillis = builder.mNativeIndexRestorationLatencyMillis; 250 mNativeSchemaStoreRecoveryLatencyMillis = builder.mNativeSchemaStoreRecoveryLatencyMillis; 251 mNativeDocumentStoreDataStatus = builder.mNativeDocumentStoreDataStatus; 252 mNativeNumDocuments = builder.mNativeNumDocuments; 253 mNativeNumSchemaTypes = builder.mNativeNumSchemaTypes; 254 mHasReset = builder.mHasReset; 255 mResetStatusCode = builder.mResetStatusCode; 256 } 257 258 /** Builder for {@link InitializeStats}. */ 259 public static class Builder { 260 @AppSearchResult.ResultCode int mStatusCode; 261 262 int mTotalLatencyMillis; 263 boolean mHasDeSync; 264 int mPrepareSchemaAndNamespacesLatencyMillis; 265 int mPrepareVisibilityStoreLatencyMillis; 266 int mNativeLatencyMillis; 267 @RecoveryCause int mNativeDocumentStoreRecoveryCause; 268 @RecoveryCause int mNativeIndexRestorationCause; 269 @RecoveryCause int mNativeSchemaStoreRecoveryCause; 270 int mNativeDocumentStoreRecoveryLatencyMillis; 271 int mNativeIndexRestorationLatencyMillis; 272 int mNativeSchemaStoreRecoveryLatencyMillis; 273 @DocumentStoreDataStatus int mNativeDocumentStoreDataStatus; 274 int mNativeNumDocuments; 275 int mNativeNumSchemaTypes; 276 boolean mHasReset; 277 @AppSearchResult.ResultCode int mResetStatusCode; 278 279 /** Sets the status of the initialization. */ 280 @NonNull setStatusCode(@ppSearchResult.ResultCode int statusCode)281 public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) { 282 mStatusCode = statusCode; 283 return this; 284 } 285 286 /** Sets the total latency of the initialization in milliseconds. */ 287 @NonNull setTotalLatencyMillis(int totalLatencyMillis)288 public Builder setTotalLatencyMillis(int totalLatencyMillis) { 289 mTotalLatencyMillis = totalLatencyMillis; 290 return this; 291 } 292 293 /** 294 * Sets whether the initialize() detects deSync. 295 * 296 * <p>If there is a deSync, it means AppSearch and IcingSearchEngine have an inconsistent 297 * view of what data should exist. 298 */ 299 @NonNull setHasDeSync(boolean hasDeSync)300 public Builder setHasDeSync(boolean hasDeSync) { 301 mHasDeSync = hasDeSync; 302 return this; 303 } 304 305 /** Sets time used to read and process the schema and namespaces. */ 306 @NonNull setPrepareSchemaAndNamespacesLatencyMillis( int prepareSchemaAndNamespacesLatencyMillis)307 public Builder setPrepareSchemaAndNamespacesLatencyMillis( 308 int prepareSchemaAndNamespacesLatencyMillis) { 309 mPrepareSchemaAndNamespacesLatencyMillis = prepareSchemaAndNamespacesLatencyMillis; 310 return this; 311 } 312 313 /** Sets time used to read and process the visibility file. */ 314 @NonNull setPrepareVisibilityStoreLatencyMillis( int prepareVisibilityStoreLatencyMillis)315 public Builder setPrepareVisibilityStoreLatencyMillis( 316 int prepareVisibilityStoreLatencyMillis) { 317 mPrepareVisibilityStoreLatencyMillis = prepareVisibilityStoreLatencyMillis; 318 return this; 319 } 320 321 /** Sets overall time used for the native function call. */ 322 @NonNull setNativeLatencyMillis(int nativeLatencyMillis)323 public Builder setNativeLatencyMillis(int nativeLatencyMillis) { 324 mNativeLatencyMillis = nativeLatencyMillis; 325 return this; 326 } 327 328 /** 329 * Sets recovery cause for document store. 330 * 331 * <p>Possible recovery causes for document store: 332 * <li>{@link InitializeStats#RECOVERY_CAUSE_DATA_LOSS} 333 * <li>{@link InitializeStats#RECOVERY_CAUSE_TOTAL_CHECKSUM_MISMATCH} 334 * <li>{@link InitializeStats#RECOVERY_CAUSE_IO_ERROR} 335 */ 336 @NonNull setDocumentStoreRecoveryCause( @ecoveryCause int documentStoreRecoveryCause)337 public Builder setDocumentStoreRecoveryCause( 338 @RecoveryCause int documentStoreRecoveryCause) { 339 mNativeDocumentStoreRecoveryCause = documentStoreRecoveryCause; 340 return this; 341 } 342 343 /** 344 * Sets restoration cause for index store. 345 * 346 * <p>Possible causes: 347 * <li>{@link InitializeStats#DOCUMENT_STORE_DATA_STATUS_COMPLETE_LOSS} 348 * <li>{@link InitializeStats#RECOVERY_CAUSE_TOTAL_CHECKSUM_MISMATCH} 349 * <li>{@link InitializeStats#RECOVERY_CAUSE_IO_ERROR} 350 */ 351 @NonNull setIndexRestorationCause(@ecoveryCause int indexRestorationCause)352 public Builder setIndexRestorationCause(@RecoveryCause int indexRestorationCause) { 353 mNativeIndexRestorationCause = indexRestorationCause; 354 return this; 355 } 356 357 /** 358 * Returns recovery cause for schema store. 359 * 360 * <p>Possible causes: 361 * <li>{@link InitializeStats#RECOVERY_CAUSE_IO_ERROR} 362 */ 363 @NonNull setSchemaStoreRecoveryCause(@ecoveryCause int schemaStoreRecoveryCause)364 public Builder setSchemaStoreRecoveryCause(@RecoveryCause int schemaStoreRecoveryCause) { 365 mNativeSchemaStoreRecoveryCause = schemaStoreRecoveryCause; 366 return this; 367 } 368 369 /** Sets time used to recover the document store. */ 370 @NonNull setDocumentStoreRecoveryLatencyMillis( int documentStoreRecoveryLatencyMillis)371 public Builder setDocumentStoreRecoveryLatencyMillis( 372 int documentStoreRecoveryLatencyMillis) { 373 mNativeDocumentStoreRecoveryLatencyMillis = documentStoreRecoveryLatencyMillis; 374 return this; 375 } 376 377 /** Sets time used to restore the index. */ 378 @NonNull setIndexRestorationLatencyMillis(int indexRestorationLatencyMillis)379 public Builder setIndexRestorationLatencyMillis(int indexRestorationLatencyMillis) { 380 mNativeIndexRestorationLatencyMillis = indexRestorationLatencyMillis; 381 return this; 382 } 383 384 /** Sets time used to recover the schema store. */ 385 @NonNull setSchemaStoreRecoveryLatencyMillis(int schemaStoreRecoveryLatencyMillis)386 public Builder setSchemaStoreRecoveryLatencyMillis(int schemaStoreRecoveryLatencyMillis) { 387 mNativeSchemaStoreRecoveryLatencyMillis = schemaStoreRecoveryLatencyMillis; 388 return this; 389 } 390 391 /** 392 * Sets Native Document Store Data status. status is defined in 393 * external/icing/proto/icing/proto/logging.proto 394 */ 395 @NonNull setDocumentStoreDataStatus( @ocumentStoreDataStatus int documentStoreDataStatus)396 public Builder setDocumentStoreDataStatus( 397 @DocumentStoreDataStatus int documentStoreDataStatus) { 398 mNativeDocumentStoreDataStatus = documentStoreDataStatus; 399 return this; 400 } 401 402 /** 403 * Sets number of documents currently in document store. Those may include alive, deleted, 404 * and expired documents. 405 */ 406 @NonNull setDocumentCount(int numDocuments)407 public Builder setDocumentCount(int numDocuments) { 408 mNativeNumDocuments = numDocuments; 409 return this; 410 } 411 412 /** Sets number of schema types currently in the schema store. */ 413 @NonNull setSchemaTypeCount(int numSchemaTypes)414 public Builder setSchemaTypeCount(int numSchemaTypes) { 415 mNativeNumSchemaTypes = numSchemaTypes; 416 return this; 417 } 418 419 /** Sets whether we had to reset the index, losing all data, as part of initialization. */ 420 @NonNull setHasReset(boolean hasReset)421 public Builder setHasReset(boolean hasReset) { 422 mHasReset = hasReset; 423 return this; 424 } 425 426 /** Sets the status of the reset, if one was performed according to {@link #setHasReset}. */ 427 @NonNull setResetStatusCode(@ppSearchResult.ResultCode int resetStatusCode)428 public Builder setResetStatusCode(@AppSearchResult.ResultCode int resetStatusCode) { 429 mResetStatusCode = resetStatusCode; 430 return this; 431 } 432 433 /** 434 * Constructs a new {@link InitializeStats} from the contents of this {@link 435 * InitializeStats.Builder} 436 */ 437 @NonNull build()438 public InitializeStats build() { 439 return new InitializeStats(/* builder= */ this); 440 } 441 } 442 } 443