aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/research/FixedLogBuffer.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/research/FixedLogBuffer.java')
-rw-r--r--java/src/com/android/inputmethod/research/FixedLogBuffer.java72
1 files changed, 42 insertions, 30 deletions
diff --git a/java/src/com/android/inputmethod/research/FixedLogBuffer.java b/java/src/com/android/inputmethod/research/FixedLogBuffer.java
index 78dc59562..8b64de8ae 100644
--- a/java/src/com/android/inputmethod/research/FixedLogBuffer.java
+++ b/java/src/com/android/inputmethod/research/FixedLogBuffer.java
@@ -51,38 +51,36 @@ public class FixedLogBuffer extends LogBuffer {
mNumActualWords = 0;
}
- protected int getNumActualWords() {
- return mNumActualWords;
- }
-
/**
* Adds a new LogUnit to the front of the LIFO queue, evicting existing LogUnit's
* (oldest first) if word capacity is reached.
*/
@Override
public void shiftIn(final LogUnit newLogUnit) {
- if (!newLogUnit.hasWord()) {
- // This LogUnit isn't a word, so it doesn't count toward the word-limit.
+ if (!newLogUnit.hasOneOrMoreWords()) {
+ // This LogUnit doesn't contain any word, so it doesn't count toward the word-limit.
super.shiftIn(newLogUnit);
return;
}
+ final int numWordsIncoming = newLogUnit.getNumWords();
if (mNumActualWords >= mWordCapacity) {
// Give subclass a chance to handle the buffer full condition by shifting out logUnits.
+ // TODO: Tell onBufferFull() how much space it needs to make to avoid forced eviction.
onBufferFull();
// If still full, evict.
if (mNumActualWords >= mWordCapacity) {
- shiftOutWords(1);
+ shiftOutWords(numWordsIncoming);
}
}
super.shiftIn(newLogUnit);
- mNumActualWords++; // Must be a word, or we wouldn't be here.
+ mNumActualWords += numWordsIncoming;
}
@Override
public LogUnit unshiftIn() {
final LogUnit logUnit = super.unshiftIn();
- if (logUnit != null && logUnit.hasWord()) {
- mNumActualWords--;
+ if (logUnit != null && logUnit.hasOneOrMoreWords()) {
+ mNumActualWords -= logUnit.getNumWords();
}
return logUnit;
}
@@ -113,18 +111,28 @@ public class FixedLogBuffer extends LogBuffer {
@Override
public LogUnit shiftOut() {
final LogUnit logUnit = super.shiftOut();
- if (logUnit != null && logUnit.hasWord()) {
- mNumActualWords--;
+ if (logUnit != null && logUnit.hasOneOrMoreWords()) {
+ mNumActualWords -= logUnit.getNumWords();
}
return logUnit;
}
- protected void shiftOutWords(final int numWords) {
- final int targetNumWords = mNumActualWords - numWords;
- final LinkedList<LogUnit> logUnits = getLogUnits();
- while (mNumActualWords > targetNumWords && !logUnits.isEmpty()) {
- shiftOut();
- }
+ /**
+ * Remove LogUnits from the front of the LogBuffer until {@code numWords} have been removed.
+ *
+ * If there are less than {@code numWords} in the buffer, shifts out all {@code LogUnit}s.
+ *
+ * @param numWords the minimum number of words in {@link LogUnit}s to shift out
+ * @return the number of actual words LogUnit}s shifted out
+ */
+ protected int shiftOutWords(final int numWords) {
+ int numWordsShiftedOut = 0;
+ do {
+ final LogUnit logUnit = shiftOut();
+ if (logUnit == null) break;
+ numWordsShiftedOut += logUnit.getNumWords();
+ } while (numWordsShiftedOut < numWords);
+ return numWordsShiftedOut;
}
public void shiftOutAll() {
@@ -136,27 +144,31 @@ public class FixedLogBuffer extends LogBuffer {
}
/**
- * Returns a list of {@link LogUnit}s at the front of the buffer that have associated words. No
- * more than {@code n} LogUnits will have words associated with them. If there are not enough
- * LogUnits in the buffer to meet the word requirement, returns the all LogUnits.
+ * Returns a list of {@link LogUnit}s at the front of the buffer that have words associated with
+ * them.
+ *
+ * There will be no more than {@code n} words in the returned list. So if 2 words are
+ * requested, and the first LogUnit has 3 words, it is not returned. If 2 words are requested,
+ * and the first LogUnit has only 1 word, and the next LogUnit 2 words, only the first LogUnit
+ * is returned. If the first LogUnit has no words associated with it, and the second LogUnit
+ * has three words, then only the first LogUnit (which has no associated words) is returned. If
+ * there are not enough LogUnits in the buffer to meet the word requirement, then all LogUnits
+ * will be returned.
*
* @param n The maximum number of {@link LogUnit}s with words to return.
* @return The list of the {@link LogUnit}s containing the first n words
*/
public ArrayList<LogUnit> peekAtFirstNWords(int n) {
final LinkedList<LogUnit> logUnits = getLogUnits();
- final int length = logUnits.size();
// Allocate space for n*2 logUnits. There will be at least n, one for each word, and
// there may be additional for punctuation, between-word commands, etc. This should be
// enough that reallocation won't be necessary.
- final ArrayList<LogUnit> list = new ArrayList<LogUnit>(n * 2);
- for (int i = 0; i < length && n > 0; i++) {
- final LogUnit logUnit = logUnits.get(i);
- list.add(logUnit);
- if (logUnit.hasWord()) {
- n--;
- }
+ final ArrayList<LogUnit> resultList = new ArrayList<LogUnit>(n * 2);
+ for (final LogUnit logUnit : logUnits) {
+ n -= logUnit.getNumWords();
+ if (n < 0) break;
+ resultList.add(logUnit);
}
- return list;
+ return resultList;
}
}