Improved FocusSpans sorting.

Change-Id: I1853c03e371112e0e9f961e8140cc0d74c3bb65f
diff --git a/Changes b/Changes
index 4bc1f21..8df015e 100644
--- a/Changes
+++ b/Changes
@@ -14,6 +14,7 @@
     - [bugfix] Fixed left expansion match order (margaretha)
     - [bugfix] Fixed right expansion match order & expansion over start (margaretha)
     - [feature] Added opt() method to QueryBuilder (diewald)
+    - [bugfix] Improved FocusSpans sorting (margaretha)
 
 0.58.0 2018-09-03
     - [feature] Implemented referencing cached collection (margaretha)
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/FocusSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/FocusSpans.java
index c5e9487..3e5fab0 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/FocusSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/FocusSpans.java
@@ -130,9 +130,16 @@
 
     private void collectCandidates () throws IOException {
         CandidateSpan cs = null;
-        while (hasMoreSpans && candidates.size() < windowSize
-                && firstSpans.doc() == currentDoc) {
-
+        CandidateSpan head = null;
+        
+        while (hasMoreSpans && firstSpans.doc() == currentDoc) {
+            if (head == null){ 
+                head = candidates.peek();
+            }
+            else if (head.getStart() < firstSpans.start()){
+                break;
+            }
+            
             if (firstSpans.isPayloadAvailable() && updateSpanPositions(
                     cs = new CandidateSpan(firstSpans))) {
                 if (cs.getDoc() == prevDoc && cs.getStart() < prevStart) {
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestFocusIndex.java b/src/test/java/de/ids_mannheim/korap/index/TestFocusIndex.java
index f61252a..e79ae03 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestFocusIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestFocusIndex.java
@@ -103,6 +103,40 @@
         assertEquals("ab[[{1:c}]]d", kr.getMatch(2).getSnippetBrackets());
         assertEquals("ab[[{1:c}]]d", kr.getMatch(3).getSnippetBrackets());
         assertEquals(4, kr.getTotalResults());
+        
+        testFocusSortingOverWindowSize(elemX, classB, classC);
+        
+    }
+    
+    private void testFocusSortingOverWindowSize (SpanQuery elemX,
+            SpanQuery classB, SpanQuery classC) throws IOException {
+        ki.addDoc(createFieldDoc1());
+        ki.commit();
+        
+        SpanQuery termD = new SpanTermQuery(new Term("tokens", "s:d"));
+        SpanQuery classD = new SpanClassQuery(termD, (byte) 1);
+        
+        SpanQuery or = new SpanOrQuery(classB, classC, classD);
+        SpanWithinQuery within = new SpanWithinQuery(elemX, or);
+        kr = ki.search(within, (short) 10);
+        
+        assertEquals("[[abc{1:d}]]", kr.getMatch(7).getSnippetBrackets());
+        assertEquals(10, kr.getTotalResults());
+        
+        SpanFocusQuery focus = new SpanFocusQuery(within, (byte) 1);
+        focus.setSorted(false);
+        focus.setWindowSize(2);
+        kr = ki.search(focus, (short) 10);
+        
+//        for (Match m: kr.getMatches()){
+//            System.out.println(m.getDocID() + " "+m.getSnippetBrackets());
+//        }
+        assertEquals("a[[{1:b}]]cd", kr.getMatch(0).getSnippetBrackets());
+        assertEquals("a[[{1:b}]]cd", kr.getMatch(1).getSnippetBrackets());
+        assertEquals("ab[[{1:c}]]d", kr.getMatch(2).getSnippetBrackets());
+        assertEquals("ab[[{1:c}]]d", kr.getMatch(3).getSnippetBrackets());
+        assertEquals(10, kr.getTotalResults());
+
     }
 
     public static FieldDocument createFieldDoc () {
@@ -120,4 +154,20 @@
         
         return fd;
     }
+    
+    public static FieldDocument createFieldDoc1 () {
+        FieldDocument fd = new FieldDocument();
+        fd.addString("ID", "doc-1");
+        fd.addTV("tokens", "abcd",
+
+                "[(0-1)s:a|_0$<i>0<i>1|"
+                + "<>:x$<b>64<i>0<i>4<i>4<b>0]"
+                + "[(1-2)s:b|_1$<i>1<i>2]"
+                + "[(2-3)s:c|_2$<i>2<i>3|"
+                + "<>:x$<b>64<i>2<i>4<i>4<b>0]"
+                + "[(3-4)s:d|_3$<i>3<i>4]"
+                 );
+        
+        return fd;
+    }
 }