package com.onaro.sanscreen.client.view.changes; import com.onaro.sanscreen.server.dataobject.*; import java.util.*; import java.util.concurrent.*; public class ChangesChunkList extends ArrayList { private static final long serialVersionUID = 1L; public ChangesChunkList(List olderHistories,List newerHistories) { //first load the new changes from the older to the newest (otherwise there will be a gap in the changes while the chunks are loaded. LinkedList newerChunks = toChangesChunks(newerHistories); Collections.reverse(newerChunks); addAll(newerChunks); //then load all the older changes from newest to the oldest addAll(toChangesChunks(olderHistories)); } private LinkedList toChangesChunks(List histories) { LinkedList changesChunks = new LinkedList(); if (histories.size() > 0) { long toTime = histories.get(0).getStartTime(); int changeInChunk = 0; for (Iterator historyItr = histories.iterator(); historyItr.hasNext();) { UpdateHistory history = historyItr.next(); changeInChunk += history.isLogChanges() ? history.getTotalChange(): 0; long fromTime = history.getStartTime(); if (changeInChunk > ChangesConfig.getChunkSize() || (!historyItr.hasNext() && changeInChunk > 0)) { changesChunks.add(new ChangesChunk(fromTime, toTime, changeInChunk)); toTime = fromTime - 1; changeInChunk = 0; } } } return changesChunks; } public ChangesChunkList(long from,long to, Changes changes) { add(new ChangesChunk(from, to, changes)); } /** * Blocks until a changes chunk is done loading - whether by completing loading, failing or cancelled. * The timeout is proportional to the index. this is because launching of chunks with higher index is delayed. * @param index in the array of chunks * @return the chunk if is done. null if the chucnk wasn'tt done by the timeout * @throws InterruptedException if the thread is interrupted */ public ChangesChunk getChunkWhenDone(int index) throws InterruptedException, TimeoutException { long timeoutInMillis = ChangesConfig.getChunkLoadWaitTimeoutMillis() + (index * ChangesConfig.getDelayBetweenChunksLoadMillis() * 2); return get(index).getWhenDone(timeoutInMillis); } public String toString() { int total = 0; StringBuilder content = new StringBuilder(); for (ChangesChunk chunk : this) { total += chunk.getNumberOfChanges(); content.append(chunk.getNumberOfChanges()).append(','); } final StringBuilder sb = new StringBuilder(); sb.append("ChangesChunkList"); //$NON-NLS-1$ sb.append("{total=").append(total).append("; list of chunks sizes=").append(content).append("}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ return sb.toString(); } }