1 /*
2  * Copyright (C) 2023 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.cobalt.data;
18 
19 import androidx.annotation.NonNull;
20 import androidx.room.ColumnInfo;
21 import androidx.room.Embedded;
22 import androidx.room.Entity;
23 import androidx.room.Ignore;
24 import androidx.room.Index;
25 
26 import com.android.internal.annotations.VisibleForTesting;
27 
28 import com.google.auto.value.AutoValue;
29 import com.google.auto.value.AutoValue.CopyAnnotations;
30 import com.google.common.hash.HashCode;
31 import com.google.common.hash.Hashing;
32 
33 /**
34  * Stores the unique string hashes logged to a report on a given day and their index in the string
35  * list for the report, day combination.
36  */
37 @AutoValue
38 @CopyAnnotations
39 @Entity(
40         tableName = "StringHashes",
41         primaryKeys = {
42             "customer_id",
43             "project_id",
44             "metric_id",
45             "report_id",
46             "day_index",
47             "list_index",
48         },
49         indices = {
50             @Index(
51                     value = {
52                         "customer_id",
53                         "project_id",
54                         "metric_id",
55                         "report_id",
56                         "day_index",
57                         "string_hash"
58                     },
59                     unique = true)
60         })
61 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
62 public abstract class StringHashEntity {
63     /** Values uniquely identifying the report. */
64     @CopyAnnotations
65     @Embedded
66     @NonNull
reportKey()67     abstract ReportKey reportKey();
68 
69     /** The day the string hash was logged on. */
70     @CopyAnnotations
71     @ColumnInfo(name = "day_index")
72     @NonNull
dayIndex()73     abstract int dayIndex();
74 
75     /** The index of the string hash in the hash list. */
76     @CopyAnnotations
77     @ColumnInfo(name = "list_index")
78     @NonNull
listIndex()79     abstract int listIndex();
80 
81     /** The string hash. */
82     @CopyAnnotations
83     @ColumnInfo(name = "string_hash")
84     @NonNull
stringHash()85     abstract HashCode stringHash();
86 
87     /**
88      * Creates an {@link StringHashEntity}.
89      *
90      * <p>Used by Room to instantiate objects.
91      */
92     @NonNull
create( ReportKey reportKey, int dayIndex, int listIndex, HashCode stringHash)93     static StringHashEntity create(
94             ReportKey reportKey, int dayIndex, int listIndex, HashCode stringHash) {
95         return new AutoValue_StringHashEntity(reportKey, dayIndex, listIndex, stringHash);
96     }
97 
98     /** Creates an {@link StringHashEntity}. */
99     @Ignore
100     @NonNull
101     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
create( ReportKey reportKey, int dayIndex, int listIndex, String string)102     public static StringHashEntity create(
103             ReportKey reportKey, int dayIndex, int listIndex, String string) {
104         return new AutoValue_StringHashEntity(reportKey, dayIndex, listIndex, getHash(string));
105     }
106 
107     /** Creates a hash of the input value that's usable for observation generation */
getHash(String value)108     static HashCode getHash(String value) {
109         return Hashing.farmHashFingerprint64().hashBytes(value.getBytes());
110     }
111 }
112