package sssj.index.streaming.component;

import it.unimi.dsi.fastutil.longs.Long2ReferenceLinkedOpenHashMap;
import it.unimi.dsi.fastutil.longs.Long2ReferenceMap.Entry;

import java.util.Iterator;

import sssj.io.Vector;

public class StreamingResiduals implements Iterable<Vector> {
  private Long2ReferenceLinkedOpenHashMap<Vector> map = new Long2ReferenceLinkedOpenHashMap<>();

  public void add(Vector residual) {
    map.put(residual.timestamp(), residual);
  }

  @Override
  public Iterator<Vector> iterator() {
    return map.values().iterator();
  }

  @Override
  public String toString() {
    return "Residuals = [" + map + "]";
  }

  public Vector get(long candidateID) {
    return map.get(candidateID);
  }

  /**
   * Get the residual of the vector with id {@code candidateID}, while at the same time pruning all the residuals with timestamp less than {@code lowWatermark}.
   *
   * @param candidateID the id of the candidate vector
   * @param lowWatermark the minimum id of the vector to be retained
   * @return the residual of the candidate
   */
  public Vector getAndPrune(long candidateID, long lowWatermark) {
    for (Iterator<Entry<Vector>> it = map.long2ReferenceEntrySet().fastIterator(); it.hasNext();) {
      final Vector v = it.next().getValue();
      if (lowWatermark > v.timestamp())
        it.remove();
      // FIXME optimize pruning
      if (candidateID == v.timestamp())
        return v;
    }
    return null;
  }
}
@@ -379,95 +379,8 @@
 );%0A%0A
-  public void add(Vector residual) %7B%0A    map.put(residual.timestamp(), residual);%0A  %7D%0A%0A
   @O
@@ -473,162 +473,85 @@
 %0A%0A  
-@Override%0A  public String toString() %7B%0A    return %22Residuals = %5B%22 + map + %22%5D%22;%0A  %7D%0A%0A  public Vector get(long candidateID) %7B%0A    return map.get(candidateID
+public void add(Vector residual) %7B%0A    map.put(residual.timestamp(), residual
 );%0A 
@@ -974,13 +974,8 @@
     
-for (
 Iter
@@ -1047,243 +1047,229 @@
 r();
- it.hasNext();) %7B%0A      final Vector v = it.next().getValue();%0A      if (lowWatermark %3E v.timestamp())%0A        it.remove();%0A      // FIXME optimize pruning%0A      if (candidateID == v.timestamp())%0A        return v;%0A    %7D%0A    return null
+%0A    while (it.hasNext() && it.next().getValue().timestamp() %3C lowWatermark) %7B%0A      it.remove();%0A    %7D%0A    return map.get(candidateID);%0A  %7D%0A%0A  @Override%0A  public String toString() %7B%0A    return %22Residuals = %5B%22 + map + %22%5D%22
 ;%0A  

Optimize streaming residuals