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.server.healthconnect.storage.datatypehelpers.aggregation;
18 
19 import android.annotation.IntDef;
20 
21 import java.util.List;
22 
23 /**
24  * Class which represents timestamp of the data to aggregate.
25  *
26  * @hide
27  */
28 public class AggregationTimestamp implements Comparable<AggregationTimestamp> {
29 
30     @IntDef({GROUP_BORDER, INTERVAL_START, INTERVAL_END})
31     public @interface TimestampType {}
32 
33     // Note: values matter for ordering in compareBy
34     public static final int GROUP_BORDER = 0;
35     public static final int INTERVAL_START = 1;
36     public static final int INTERVAL_END = 2;
37 
38     private static final List<String> TYPE_PRINT_NAMES = List.of("GROUP_BORDER", "START", "END");
39 
40     @TimestampType private final int mType;
41     private final long mTime;
42     private AggregationRecordData mParentRecord;
43 
44     @SuppressWarnings("NullAway.Init") // TODO(b/317029272): fix this suppression
AggregationTimestamp(int type, long time)45     public AggregationTimestamp(int type, long time) {
46         mTime = time;
47         mType = type;
48     }
49 
getType()50     int getType() {
51         return mType;
52     }
53 
getTime()54     long getTime() {
55         return mTime;
56     }
57 
getParentData()58     AggregationRecordData getParentData() {
59         return mParentRecord;
60     }
61 
setParentData(AggregationRecordData parentRecord)62     AggregationTimestamp setParentData(AggregationRecordData parentRecord) {
63         mParentRecord = parentRecord;
64         return this;
65     }
66 
67     @Override
compareTo(AggregationTimestamp o)68     public int compareTo(AggregationTimestamp o) {
69         if (this.equals(o)) {
70             return 0;
71         }
72 
73         if (getTime() == o.getTime()) {
74             // We sort in the following order:
75             // all group borders first as group intervals are inclusive for start,
76             // exclusive for end. Then all intervals starts, then all intervals ends.
77             // If types are equal, sort by priority, if still equal by last modified time.
78             if (getType() != o.getType()) {
79                 return getType() - o.getType();
80             }
81 
82             // Equal type and time can happen only if both are either starts or ends of intervals,
83             // hence parentData is not null for both. ParentData is null only for group border.
84             return getParentData().compareTo(o.getParentData());
85         } else if (getTime() < o.getTime()) {
86             return -1;
87         } else {
88             return 1;
89         }
90     }
91 
92     @Override
toString()93     public String toString() {
94         return "Timestamp{type="
95                 + TYPE_PRINT_NAMES.get(mType)
96                 + ", time="
97                 + mTime
98                 + ", parentData="
99                 + (mParentRecord == null ? "null" : mParentRecord)
100                 + "}";
101     }
102 }
103