package org.helioviewer.jhv.plugins.pfss.data;

import org.helioviewer.jhv.plugins.pfss.PfssSettings;

// Datastructure to cache the Pfss-Data with preload function
public class PfssCache {

    private final PfssData[] data = new PfssData[PfssSettings.CACHE_SIZE];
    private int numberOfElementsInCache = 0;

    public void addData(PfssData pfssData) {
        if (numberOfElementsInCache < PfssSettings.CACHE_SIZE) {
            data[numberOfElementsInCache] = pfssData;
            numberOfElementsInCache++;
            bubbleSort();
        }
    }

    private void bubbleSort() {
        boolean swapped = true;
        int j = 0;
        while (swapped) {
            swapped = false;
            j++;
            for (int i = 0; i < numberOfElementsInCache - j; i++) {
                if (data[i].dateObs.milli > data[i + 1].dateObs.milli) {
                    PfssData tmp = data[i];
                    data[i] = data[i + 1];
                    data[i + 1] = tmp;
                    swapped = true;
                }
            }
        }
    }

    public PfssData getData(long timestamp) {
        if (numberOfElementsInCache <= 0)
            return null;

        int found = binarySearch(timestamp);
        if (found >= 0)
            return data[found];

        if (-found >= numberOfElementsInCache)
            return data[numberOfElementsInCache - 1];

        if (-found - 1 >= 0) {
            long diff1 = Math.abs(data[-found - 1].dateObs.milli - timestamp);
            long diff2 = Math.abs(data[-found].dateObs.milli - timestamp);
            if (diff1 < diff2) {
                return data[-found - 1];
            }
        }
        return data[-found];
    }

    private int binarySearch(long timestamp) {
        int low = 0;
        int high = numberOfElementsInCache - 1;

        while (low <= high) {
            int mid = (low + high) >>> 1;
            long midVal = data[mid].dateObs.milli;

            if (midVal < timestamp)
                low = mid + 1;
            else if (midVal > timestamp)
                high = mid - 1;
            else
                return mid;
        }
        return -(low + 1);
    }

    public void clear() {
        numberOfElementsInCache = 0;
        for (int i = 0; i < data.length; i++) {
            data[i] = null;
        }
    }

}

@@ -41,16 +41,43 @@
 .data;%0A%0A
+import java.util.TreeMap;%0A%0A
 import o
@@ -127,214 +127,97 @@
 s;%0A%0A
-// Datastructure to cache the Pfss-Data with preload function%0Apublic class PfssCache %7B%0A%0A    private final PfssData%5B%5D data = new PfssData%5BPfssSettings.CACHE_SIZE%5D;%0A    private int numberOfElementsInCache = 0
+public class PfssCache %7B%0A%0A    private final TreeMap%3CLong, PfssData%3E map = new TreeMap%3C%3E()
 ;%0A%0A 
@@ -248,21 +248,17 @@
 fssData 
-pfssD
+d
 ata) %7B%0A 
@@ -268,451 +268,73 @@
     
-if (numberOfElementsInCache %3C PfssSettings.CACHE_SIZE) %7B%0A            data%5BnumberOfElementsInCache%5D = pfssData;%0A            numberOfElementsInCache++;%0A            bubbleSort();%0A        %7D%0A    %7D%0A%0A    private void bubbleSort() %7B%0A        boolean swapped = true;%0A        int j = 0;%0A        while (swapped) %7B%0A            swapped = false;%0A            j++;%0A            for (int i = 0; i %3C numberOfElementsInCache - j; i++) %7B%0A                if (data%5Bi%5D
+assert map.size() %3C PfssSettings.CACHE_SIZE;%0A        map.put(data
 .dat
@@ -347,397 +347,143 @@
 illi
- %3E
+,
  data
-%5Bi + 1%5D.dateObs.milli) %7B%0A                    PfssData tmp = data%5Bi%5D;%0A                    data%5Bi%5D = data%5Bi + 1%5D;%0A                    data%5Bi + 1%5D = tmp;%0A                    swapped = true;%0A                %7D%0A            %7D%0A        %7D%0A    %7D%0A%0A    public PfssData getData(long timestamp) %7B%0A        if (numberOfElementsInCache %3C= 0)%0A            return null;%0A%0A        int found = binarySearch
+);%0A    %7D%0A%0A    public PfssData getData(long timestamp) %7B%0A        Long c = map.ceilingKey(timestamp);%0A        Long f = map.floorKey
 (tim
@@ -483,32 +483,33 @@
 Key(timestamp);%0A
+%0A
         if (foun
@@ -508,372 +508,100 @@
 if (
-found %3E= 0)%0A            return data%5Bfound%5D;%0A%0A        if (-found %3E= numberOfElementsInCache)%0A            return data%5BnumberOfElementsInCache - 1%5D;%0A%0A        if (-found - 1 %3E= 0) %7B%0A            long diff1 = Math.abs(data%5B-found - 1%5D.dateObs.milli - timestamp);%0A            long diff2 = Math.abs(data%5B-found%5D.dateObs.milli - timestamp);%0A            if (diff1 %3C diff2) %7B
+c != null && f != null) %7B%0A            if (Math.abs(f - timestamp) %3C Math.abs(timestamp - c))
 %0A   
@@ -624,24 +624,18 @@
 urn 
-data%5B-found - 1%5D
+map.get(f)
 ;%0A  
@@ -636,33 +636,36 @@
 f);%0A            
-%7D
+else
 %0A        %7D%0A     
@@ -649,34 +649,32 @@
    else%0A        
-%7D%0A
         return d
@@ -676,454 +676,174 @@
 urn 
-data%5B-found%5D;%0A    %7D%0A%0A    private int binarySearch(long timestamp) %7B%0A        int low = 0;%0A        int high = numberOfElementsInCache - 1;%0A%0A        while (low %3C= high) %7B%0A            int mid = (low + high) %3E%3E%3E 1;%0A            long midVal = data%5Bmid%5D.dateObs.milli;%0A%0A            if (midVal %3C timestamp)%0A                low = mid + 1;%0A            else if (midVal %3E timestamp)%0A                high = mid - 1;%0A            else%0A                return mid;
+map.get(c);%0A        %7D%0A%0A        try %7B%0A            if (f == null)%0A                return map.get(c);%0A            return map.get(f);%0A        %7D catch (Exception ignore) %7B
 %0A   
@@ -845,24 +845,25 @@
 %7B%0A        %7D%0A
+%0A
         retu
@@ -869,18 +869,12 @@
 urn 
--(low + 1)
+null
 ;%0A  
@@ -916,122 +916,20 @@
     
-numberOfElementsInCache = 0;%0A        for (int i = 0; i %3C data.length; i++) %7B%0A            data%5Bi%5D = null;%0A        %7D
+map.clear();
 %0A   

Replace PfssCache with TreeMap