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