Home | History | Annotate | Download | only in logcat
      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.ArrayList;
     20 import java.util.List;
     21 import java.util.concurrent.ArrayBlockingQueue;
     22 import java.util.concurrent.BlockingQueue;
     23 
     24 /**
     25  * Container for a list of log messages. The list of messages are
     26  * maintained in a circular buffer (FIFO).
     27  */
     28 public final class LogCatMessageList {
     29     /** Preference key for size of the FIFO. */
     30     public static final String MAX_MESSAGES_PREFKEY =
     31             "logcat.messagelist.max.size";
     32 
     33     /** Default value for max # of messages. */
     34     public static final int MAX_MESSAGES_DEFAULT = 5000;
     35 
     36     private int mFifoSize;
     37     private BlockingQueue<LogCatMessage> mQ;
     38 
     39     /**
     40      * Construct an empty message list.
     41      * @param maxMessages capacity of the circular buffer
     42      */
     43     public LogCatMessageList(int maxMessages) {
     44         mFifoSize = maxMessages;
     45 
     46         mQ = new ArrayBlockingQueue<LogCatMessage>(mFifoSize);
     47     }
     48 
     49     /**
     50      * Resize the message list.
     51      * @param n new size for the list
     52      */
     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 
     69     /**
     70      * Append a message to the list. If the list is full, the first
     71      * message will be popped off of it.
     72      * @param m log to be inserted
     73      */
     74     public synchronized void appendMessages(final List<LogCatMessage> messages) {
     75         ensureSpace(messages.size());
     76         for (LogCatMessage m: messages) {
     77             mQ.offer(m);
     78         }
     79     }
     80 
     81     /**
     82      * Ensure that there is sufficient space for given number of messages.
     83      * @return list of messages that were deleted to create additional space.
     84      */
     85     public synchronized List<LogCatMessage> ensureSpace(int messageCount) {
     86         List<LogCatMessage> l = new ArrayList<LogCatMessage>(messageCount);
     87 
     88         while (mQ.remainingCapacity() < messageCount) {
     89             l.add(mQ.poll());
     90         }
     91 
     92         return l;
     93     }
     94 
     95     /**
     96      * Returns the number of additional elements that this queue can
     97      * ideally (in the absence of memory or resource constraints)
     98      * accept without blocking.
     99      * @return the remaining capacity
    100      */
    101     public synchronized int remainingCapacity() {
    102         return mQ.remainingCapacity();
    103     }
    104 
    105     /** Clear all messages in the list. */
    106     public synchronized void clear() {
    107         mQ.clear();
    108     }
    109 
    110     /** Obtain a copy of the message list. */
    111     public synchronized List<LogCatMessage> getAllMessages() {
    112         return new ArrayList<LogCatMessage>(mQ);
    113     }
    114 }
    115