Fixed #53 - element distance query bug.

Change-Id: I1504295650b1a15c0b372da776f10b203dd0080b
diff --git a/Changes b/Changes
index b0aab67..a17eeca 100644
--- a/Changes
+++ b/Changes
@@ -11,6 +11,7 @@
     - [feature] Instead of adding, the Indexer now upserts documents
       to avoid multiple documents with the same text sigle
       (diewald)
+    - [bugfix] Fixed #53 element distance query bug (margaretha)
 
 0.58.4 2019-02-05
     - [cleanup] Remove deprecated methods setLicense/getLicense,
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedDistanceSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedDistanceSpans.java
index 06227e2..6bf8cbd 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedDistanceSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedDistanceSpans.java
@@ -8,6 +8,8 @@
 import java.util.List;
 import java.util.Map;
 
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.index.TermContext;
@@ -32,6 +34,7 @@
     private long matchCost;
     protected int currentDocNum;
 
+    private Logger log = LogManager.getLogger(UnorderedDistanceSpans.class);
 
     /**
      * Constructs UnorderedDistanceSpans for the given
@@ -158,18 +161,21 @@
                 }
             }
         }
-        else if (firstSpanList.isEmpty()) {
+        else if (!secondSpanList.isEmpty()) {
             // log.trace("current target: " + secondSpanList.get(0).getStart()
             // + " " + secondSpanList.get(0).getEnd());
             // log.trace("candidates: empty");
             updateList(secondSpanList);
         }
-        else {
+        else if (!firstSpanList.isEmpty()) {
             // log.trace("current target: " + firstSpanList.get(0).getStart()
             // + " " + firstSpanList.get(0).getEnd());
             // log.trace("candidates: empty");
             updateList(firstSpanList);
         }
+        else{
+            log.debug("Both candidate lists empty");
+        }
     }
 
 
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedElementDistanceSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedElementDistanceSpans.java
index 388e97b..f111c29 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedElementDistanceSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedElementDistanceSpans.java
@@ -6,6 +6,8 @@
 import java.util.List;
 import java.util.Map;
 
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.index.TermContext;
@@ -33,6 +35,8 @@
     // target span
     private List<CandidateSpan> elementList;
 
+    private Logger log = LogManager.getLogger(UnorderedElementDistanceSpans.class);
+    boolean DEBUG = false;
 
     /**
      * Constructs UnorderedElementDistanceSpans for the given
@@ -75,6 +79,11 @@
                         hasMoreFirstSpans);
                 hasMoreSecondSpans = addSpan(secondSpans, secondSpanList,
                         hasMoreSecondSpans);
+                
+                if (DEBUG){
+                    log.debug("prepare firstSpanList: " +firstSpanList.size());
+                    log.debug("prepare secondSpanList: " +secondSpanList.size());
+                }
             }
             else {
                 hasMoreSpans = false;
@@ -263,6 +272,7 @@
 
     @Override
     protected void updateList (List<CandidateSpan> candidateList) {
+//        if (DEBUG) log.debug("candidate list size: " +candidateList.size());
         updateElementList(candidateList.get(0).getPosition());
         candidateList.remove(0);
     }
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestUnorderedElementDistanceIndex.java b/src/test/java/de/ids_mannheim/korap/index/TestUnorderedElementDistanceIndex.java
index c625818..6f3a2a5 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestUnorderedElementDistanceIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestUnorderedElementDistanceIndex.java
@@ -17,6 +17,7 @@
 import de.ids_mannheim.korap.query.SpanElementQuery;
 import de.ids_mannheim.korap.query.SpanNextQuery;
 import de.ids_mannheim.korap.response.Result;
+import de.ids_mannheim.korap.util.QueryException;
 
 @RunWith(JUnit4.class)
 public class TestUnorderedElementDistanceIndex {
@@ -93,7 +94,7 @@
 
     private FieldDocument createFieldDoc5 () {
         FieldDocument fd = new FieldDocument();
-        fd.addString("ID", "doc-2");
+        fd.addString("ID", "doc-5");
         fd.addTV("base", "text",
                 "[(0-1)s:b|_1$<i>0<i>1|<>:s$<b>64<i>0<i>2<i>2<b>0|<>:p$<b>64<i>0<i>4<i>4<b>0]"
                         + "[(1-2)s:b|s:e|_2$<i>1<i>2]"
@@ -104,6 +105,20 @@
                         + "[(6-7)s:b|_7$<i>6<i>7|<>:s$<b>64<i>6<i>7<i>7<b>0|<>:p$<b>64<i>6<i>7<i>7<b>0]");
         return fd;
     }
+    
+    private FieldDocument createFieldDoc6 () {
+        FieldDocument fd = new FieldDocument();
+        fd.addString("ID", "doc-6");
+        fd.addTV("base", "text",
+                "[(0-1)s:b|_1$<i>0<i>1|<>:s$<b>64<i>0<i>2<i>2<b>0]"
+                        + "[(1-2)s:b|s:e|_2$<i>1<i>2]"
+                        + "[(2-3)s:e|_3$<i>2<i>3]"
+                        + "[(3-4)s:b|s:c|_4$<i>3<i>4]"
+                        + "[(4-5)s:a|_5$<i>4<i>5]"
+                        + "[(5-6)s:a|_6$<i>5<i>6]"
+                        + "[(6-7)s:b|_7$<i>6<i>7]");
+        return fd;
+    }
 
     public SpanQuery createQuery (String elementType, String x, String y,
             int minDistance, int maxDistance, boolean isOrdered) {
@@ -297,4 +312,21 @@
         assertEquals(4, kr.getMatch(7).startPos);
         assertEquals(7, kr.getMatch(7).endPos);
     }
+    
+    
+    /** Both candidate lists may be empty because the spans are not in an element span.
+     * 
+     * @throws IOException
+     * @throws QueryException
+     */
+    @Test
+    public void testBothCandidateListEmptyBug () throws IOException, QueryException {
+        ki = new KrillIndex();
+        ki.addDoc(createFieldDoc6());
+        ki.commit();
+
+        SpanQuery sq = createQuery("s", "s:a", "s:c", 1, 2, false);
+        kr = ki.search(sq, (short) 10);
+        assertEquals(0, kr.getMatches().size());
+    }
 }