1 /*
2  * Copyright (C) 2018 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.wm.utils;
18 
19 import android.util.SparseArray;
20 
21 import java.util.Arrays;
22 
23 /**
24  * Caches the result of a rotation-dependent computation.
25  *
26  * The cache is discarded once the identity of the other parameter changes.
27  *
28  * @param <T> type of the parameter to the computation
29  * @param <R> type of the result of the computation
30  */
31 public class RotationCache<T,R> {
32 
33     private final RotationDependentComputation<T,R> mComputation;
34     private final SparseArray<R> mCache = new SparseArray<>(4);
35     private T mCachedFor;
36 
RotationCache(RotationDependentComputation<T, R> computation)37     public RotationCache(RotationDependentComputation<T, R> computation) {
38         mComputation = computation;
39     }
40 
41     /**
42      * Looks up the result of the computation, or calculates it if needed.
43      *
44      * @param t a parameter to the rotation-dependent computation.
45      * @param rotation the rotation for which to perform the rotation-dependent computation.
46      * @return the result of the rotation-dependent computation.
47      */
getOrCompute(T t, int rotation)48     public R getOrCompute(T t, int rotation) {
49         if (t != mCachedFor) {
50             mCache.clear();
51             mCachedFor = t;
52         }
53         final int idx = mCache.indexOfKey(rotation);
54         if (idx >= 0) {
55             return mCache.valueAt(idx);
56         }
57         final R result = mComputation.compute(t, rotation);
58         mCache.put(rotation, result);
59         return result;
60     }
61 
62     /**
63      * A computation that takes a generic input and is dependent on the rotation. The result can
64      * be cached by {@link RotationCache}.
65      */
66     @FunctionalInterface
67     public interface RotationDependentComputation<T, R> {
compute(T t, int rotation)68         R compute(T t, int rotation);
69     }
70 }
71