1 21 24 package org.lobobrowser.util; 25 26 import java.util.*; 27 28 31 public class History implements java.io.Serializable { 32 private static final long serialVersionUID = 2257845000800300100L; 33 34 private transient ArrayList historySequence; 35 36 private final SortedSet historySortedSet = new TreeSet(); 37 private final Map historyMap = new HashMap(); 38 private final SortedSet historyTimedSet = new TreeSet(); 39 40 private int sequenceCapacity; 41 private int commonEntriesCapacity; 42 43 private transient int sequenceIndex; 44 45 49 public History(int sequenceCapacity, int commonEntriesCapacity) { 50 super(); 51 this.historySequence = new ArrayList(); 52 this.sequenceIndex = -1; 53 this.sequenceCapacity = sequenceCapacity; 54 this.commonEntriesCapacity = commonEntriesCapacity; 55 } 56 57 private void readObject(java.io.ObjectInputStream in) throws ClassNotFoundException , java.io.IOException { 58 this.historySequence = new ArrayList(); 59 this.sequenceIndex = -1; 60 in.defaultReadObject(); 61 } 62 63 66 public int getCommonEntriesCapacity() { 67 return commonEntriesCapacity; 68 } 69 70 73 public void setCommonEntriesCapacity(int commonEntriesCapacity) { 74 this.commonEntriesCapacity = commonEntriesCapacity; 75 } 76 79 public int getSequenceCapacity() { 80 return sequenceCapacity; 81 } 82 85 public void setSequenceCapacity(int sequenceCapacity) { 86 this.sequenceCapacity = sequenceCapacity; 87 } 88 89 public String getCurrentItem() { 90 if(this.sequenceIndex >= 0) { 91 return (String ) this.historySequence.get(this.sequenceIndex); 92 } 93 else { 94 return null; 95 } 96 } 97 98 public String back() { 99 if(this.sequenceIndex > 0) { 100 this.sequenceIndex--; 101 return this.getCurrentItem(); 102 } 103 else { 104 return null; 105 } 106 } 107 108 public String forward() { 109 if(this.sequenceIndex + 1 < this.historySequence.size()) { 110 this.sequenceIndex++; 111 return this.getCurrentItem(); 112 } 113 else { 114 return null; 115 } 116 } 117 118 public Collection getRecentItems(int maxNumItems) { 119 Collection items = new LinkedList(); 120 Iterator i = this.historyTimedSet.iterator(); 121 int count = 0; 122 while(i.hasNext() && count++ < maxNumItems) { 123 TimedEntry entry = (TimedEntry) i.next(); 124 items.add(entry.value); 125 } 126 return items; 127 } 128 129 public Collection getHeadMatchItems(String item, int maxNumItems) { 130 Object [] array = this.historySortedSet.toArray(); 131 int idx = Arrays.binarySearch(array, item); 132 int startIdx = idx >= 0 ? idx : (-idx - 1); 133 int count = 0; 134 Collection items = new LinkedList(); 135 for(int i = startIdx; i < array.length && (count++ < maxNumItems); i++) { 136 String potentialItem = (String ) array[i]; 137 if(potentialItem.startsWith(item)) { 138 items.add(potentialItem); 139 } 140 else { 141 break; 142 } 143 } 144 return items; 145 } 146 147 public void addAsRecentOnly(String item) { 148 TimedEntry entry = (TimedEntry) this.historyMap.get(item); 149 if(entry != null) { 150 this.historyTimedSet.remove(entry); 151 entry.touch(); 152 this.historyTimedSet.add(entry); 153 } 154 else { 155 entry = new TimedEntry(item); 156 this.historyTimedSet.add(entry); 157 this.historyMap.put(item, entry); 158 this.historySortedSet.add(item); 159 if(this.historyTimedSet.size() > this.commonEntriesCapacity) { 160 TimedEntry entryToRemove = (TimedEntry) this.historyTimedSet.last(); 162 this.historyMap.remove(entryToRemove.value); 163 this.historySortedSet.remove(entryToRemove.value); 164 this.historyTimedSet.remove(entryToRemove); 165 } 166 } 167 } 168 169 public void addItem(String item, boolean updateAsRecent) { 170 int newIndex = this.sequenceIndex + 1; 171 172 while(newIndex >= this.historySequence.size()) { 173 this.historySequence.add(null); 174 } 175 this.historySequence.set(newIndex, item); 176 this.sequenceIndex = newIndex; 177 178 int expectedSize = newIndex + 1; 179 while(this.historySequence.size() > expectedSize) { 180 this.historySequence.remove(expectedSize); 181 } 182 183 while(this.historySequence.size() > this.sequenceCapacity) { 184 this.historySequence.remove(0); 185 this.sequenceIndex--; 186 } 187 188 if(updateAsRecent) { 189 this.addAsRecentOnly(item); 190 } 191 } 192 193 private class TimedEntry implements Comparable , java.io.Serializable { 194 private static final long serialVersionUID = 2257845000000000200L; 195 private long timestamp = System.currentTimeMillis(); 196 private final String value; 197 198 201 public TimedEntry(String value) { 202 this.value = value; 203 } 204 205 public void touch() { 206 this.timestamp = System.currentTimeMillis(); 207 } 208 209 public boolean equals(Object obj) { 210 TimedEntry other = (TimedEntry) obj; 211 return other.value.equals(this.value); 212 } 213 214 217 public int compareTo(Object arg0) { 218 if(this.equals(arg0)) { 219 return 0; 220 } 221 TimedEntry other = (TimedEntry) arg0; 222 long time1 = this.timestamp; 223 long time2 = other.timestamp; 224 if(time1 > time2) { 225 return -1; 227 } 228 else if(time2 > time1){ 229 return +1; 230 } 231 else { 232 int diff = System.identityHashCode(this) - System.identityHashCode(other); 233 if(diff == 0) { 234 return +1; 235 } 236 return diff; 237 } 238 } 239 } 240 241 } 242 | Popular Tags |