• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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.ddmuilib.logcat;
18 
19 import java.util.concurrent.ArrayBlockingQueue;
20 import java.util.concurrent.BlockingQueue;
21 
22 /**
23  * Container for a list of log messages. The list of messages are
24  * maintained in a circular buffer (FIFO).
25  */
26 public final class LogCatMessageList {
27     /** Preference key for size of the FIFO. */
28     public static final String MAX_MESSAGES_PREFKEY =
29             "logcat.messagelist.max.size";
30 
31     /** Default value for max # of messages. */
32     public static final int MAX_MESSAGES_DEFAULT = 5000;
33 
34     private int mFifoSize;
35     private BlockingQueue<LogCatMessage> mQ;
36     private LogCatMessage[] mQArray;
37 
38     /**
39      * Construct an empty message list.
40      * @param maxMessages capacity of the circular buffer
41      */
LogCatMessageList(int maxMessages)42     public LogCatMessageList(int maxMessages) {
43         mFifoSize = maxMessages;
44 
45         mQ = new ArrayBlockingQueue<LogCatMessage>(mFifoSize);
46         mQArray = new LogCatMessage[mFifoSize];
47     }
48 
49     /**
50      * Resize the message list.
51      * @param n new size for the list
52      */
resize(int n)53     public synchronized void resize(int n) {
54         mFifoSize = n;
55 
56         if (mFifoSize > mQ.size()) {
57             /* if resizing to a bigger fifo, we can copy over all elements from the current mQ */
58             mQ = new ArrayBlockingQueue<LogCatMessage>(mFifoSize, true, mQ);
59         } else {
60             /* for a smaller fifo, copy over the last n entries */
61             LogCatMessage[] curMessages = mQ.toArray(new LogCatMessage[mQ.size()]);
62             mQ = new ArrayBlockingQueue<LogCatMessage>(mFifoSize);
63             for (int i = curMessages.length - mFifoSize; i < curMessages.length; i++) {
64                 mQ.offer(curMessages[i]);
65             }
66         }
67 
68         mQArray = new LogCatMessage[mFifoSize];
69     }
70 
71     /**
72      * Append a message to the list. If the list is full, the first
73      * message will be popped off of it.
74      * @param m log to be inserted
75      */
appendMessage(final LogCatMessage m)76     public synchronized void appendMessage(final LogCatMessage m) {
77         if (mQ.remainingCapacity() == 0) {
78             /* make space by removing the first entry */
79             mQ.poll();
80         }
81         mQ.offer(m);
82     }
83 
84     /**
85      * Returns the number of additional elements that this queue can
86      * ideally (in the absence of memory or resource constraints)
87      * accept without blocking.
88      * @return the remaining capacity
89      */
remainingCapacity()90     public synchronized int remainingCapacity() {
91         return mQ.remainingCapacity();
92     }
93 
94     /**
95      * Clear all messages in the list.
96      */
clear()97     public synchronized void clear() {
98         mQ.clear();
99     }
100 
101     /**
102      * Obtain all the messages currently present in the list.
103      * @return array containing all the log messages
104      */
toArray()105     public Object[] toArray() {
106         if (mQ.size() == mFifoSize) {
107             /*
108              * Once the queue is full, it stays full until the user explicitly clears
109              * all the logs. Optimize for this case by not reallocating the array.
110              */
111             return mQ.toArray(mQArray);
112         }
113         return mQ.toArray();
114     }
115 }
116