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