1 /*
2  * Copyright (C) 2015 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.messaging.util;
18 
19 /**
20  * Very simple circular array implementation.
21  *
22  * @param <E> The element type of this list.
23  * @LibraryInternal
24  */
25 public class CircularArray<E> {
26     private int mNextWriter;
27     private boolean mHasWrapped;
28     private int mMaxCount;
29     Object mList[];
30 
31     /**
32      * Constructor for CircularArray.
33      *
34      * @param count Max elements to hold in the list.
35      */
CircularArray(int count)36     public CircularArray(int count) {
37         mMaxCount = count;
38         clear();
39     }
40 
41     /**
42      * Reset the list.
43      */
clear()44     public void clear() {
45         mNextWriter = 0;
46         mHasWrapped = false;
47         mList = new Object[mMaxCount];
48     }
49 
50     /**
51      * Add an element to the end of the list.
52      *
53      * @param object The object to add.
54      */
add(E object)55     public void add(E object) {
56         mList[mNextWriter] = object;
57         ++mNextWriter;
58         if (mNextWriter == mMaxCount) {
59             mNextWriter = 0;
60             mHasWrapped = true;
61         }
62     }
63 
64     /**
65      * Get the number of elements in the list. This will be 0 <= returned count <= max count
66      *
67      * @return Elements in the circular list.
68      */
count()69     public int count() {
70         if (mHasWrapped) {
71             return mMaxCount;
72         } else {
73             return mNextWriter;
74         }
75     }
76 
77     /**
78      * Return null if the list hasn't wrapped yet. Otherwise return the next object that would be
79      * overwritten. Can be useful to avoid extra allocations.
80      *
81      * @return
82      */
83     @SuppressWarnings("unchecked")
getFree()84     public E getFree() {
85         if (!mHasWrapped) {
86             return null;
87         } else {
88             return (E) mList[mNextWriter];
89         }
90     }
91 
92     /**
93      * Get the object at index. Index 0 is the oldest item inserted into the list. Index (count() -
94      * 1) is the newest.
95      *
96      * @param index Index to retrieve.
97      * @return Object at index.
98      */
99     @SuppressWarnings("unchecked")
get(int index)100     public E get(int index) {
101         if (mHasWrapped) {
102             int wrappedIndex = index + mNextWriter;
103             if (wrappedIndex >= mMaxCount) {
104                 wrappedIndex -= mMaxCount;
105             }
106             return (E) mList[wrappedIndex];
107         } else {
108             return (E) mList[index];
109         }
110     }
111 }
112