/*******************************************************************************
* Copyright (c) 2003, 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
*******************************************************************************/
package org.eclipse.core.internal.resources;
import java.util.*;
/**
* The notification mechanism can request marker deltas for several overlapping intervals of time.
* This class maintains a history of marker deltas, and upon request can generate a map of marker
* deltas for any interval. This is done by maintaining batches of marker deltas keyed by the change
* Id at the start of that batch. When the delta factory requests a delta, it specifies the start
* generation, and this class assembles the deltas for all generations between then and the most
* recent delta.
*/
class MarkerDeltaManager {
private static final int DEFAULT_SIZE= 10;
private long[] startIds= new long[DEFAULT_SIZE];
private Map[] batches= new Map[DEFAULT_SIZE];
private int nextFree= 0;
/**
* Returns the deltas from the given start id up until the present. Returns null if there are no
* deltas for that interval.
*/
protected Map assembleDeltas(long start) {
Map result= null;
for (int i= 0; i < nextFree; i++)
if (startIds[i] >= start)
result= MarkerDelta.merge(result, batches[i]);
return result;
}
/**
* Flushes all delta batches up to but not including the given start Id.
*/
protected void resetDeltas(long startId) {
//find offset of first batch to keep
int startOffset= 0;
for (; startOffset < nextFree; startOffset++)
if (startIds[startOffset] >= startId)
break;
if (startOffset == 0)
return;
long[] newIds= startIds;
Map[] newBatches= batches;
//shrink the arrays if it has grown too large
if (startIds.length > DEFAULT_SIZE && (nextFree - startOffset < DEFAULT_SIZE)) {
newIds= new long[DEFAULT_SIZE];
newBatches= new Map[DEFAULT_SIZE];
}
//copy and compact into the new array
int remaining= nextFree - startOffset;
System.arraycopy(startIds, startOffset, newIds, 0, remaining);
System.arraycopy(batches, startOffset, newBatches, 0, remaining);
//clear the end of the array
Arrays.fill(startIds, remaining, startIds.length, 0);
Arrays.fill(batches, remaining, startIds.length, null);
startIds= newIds;
batches= newBatches;
nextFree= remaining;
}
protected Map newGeneration(long start) {
int len= startIds.length;
if (nextFree >= len) {
long[] newIds= new long[len * 2];
Map[] newBatches= new Map[len * 2];
System.arraycopy(startIds, 0, newIds, 0, len);
System.arraycopy(batches, 0, newBatches, 0, len);
startIds= newIds;
batches= newBatches;
}
startIds[nextFree]= start;
batches[nextFree]= new HashMap(11);
return batches[nextFree++];
}
}