You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by mi...@apache.org on 2021/06/23 11:53:39 UTC

[lucene] branch main updated: For stability of DisjunctionIntervalsSource.toString(), sort subSources (#193)

This is an automated email from the ASF dual-hosted git repository.

mikemccand pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/lucene.git


The following commit(s) were added to refs/heads/main by this push:
     new 495bf67  For stability of DisjunctionIntervalsSource.toString(), sort subSources (#193)
495bf67 is described below

commit 495bf6730fcf01937ea45cfa5b14f88352af07f1
Author: Michael Gibney <mi...@michaelgibney.net>
AuthorDate: Wed Jun 23 07:53:30 2021 -0400

    For stability of DisjunctionIntervalsSource.toString(), sort subSources (#193)
    
    Iterators over subSources of DisjunctionIntervalsSource may
    return elements in indeterminate order, requiring special handling
    to make toString() output stable across equivalent instances
---
 .../intervals/DisjunctionIntervalsSource.java      |  5 +++-
 .../lucene/queries/intervals/TestIntervals.java    | 30 ++++++++++++++++++++++
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/lucene/queries/src/java/org/apache/lucene/queries/intervals/DisjunctionIntervalsSource.java b/lucene/queries/src/java/org/apache/lucene/queries/intervals/DisjunctionIntervalsSource.java
index 6bb9a39..7e1a701 100644
--- a/lucene/queries/src/java/org/apache/lucene/queries/intervals/DisjunctionIntervalsSource.java
+++ b/lucene/queries/src/java/org/apache/lucene/queries/intervals/DisjunctionIntervalsSource.java
@@ -120,7 +120,10 @@ class DisjunctionIntervalsSource extends IntervalsSource {
 
   @Override
   public String toString() {
-    return subSources.stream().map(Object::toString).collect(Collectors.joining(",", "or(", ")"));
+    return subSources.stream()
+        .map(Object::toString)
+        .sorted()
+        .collect(Collectors.joining(",", "or(", ")"));
   }
 
   @Override
diff --git a/lucene/queries/src/test/org/apache/lucene/queries/intervals/TestIntervals.java b/lucene/queries/src/test/org/apache/lucene/queries/intervals/TestIntervals.java
index 57e86f8..3575ed4 100644
--- a/lucene/queries/src/test/org/apache/lucene/queries/intervals/TestIntervals.java
+++ b/lucene/queries/src/test/org/apache/lucene/queries/intervals/TestIntervals.java
@@ -19,6 +19,7 @@ package org.apache.lucene.queries.intervals;
 
 import java.io.IOException;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -401,6 +402,35 @@ public class TestIntervals extends LuceneTestCase {
         source, "field1", 3, new int[][] {{}, {0, 3, 2, 6}, {3, 6}, {}, {0, 3, 2, 6}, {}});
   }
 
+  public void testIntervalDisjunctionToStringStability() {
+    /*
+    Sanity check that the subclauses of a disjunction are presented in sorted order via the toString() method.
+    The exact order is irrelevant, but ensuring stability of output makes the output more useful; e.g., for external
+    comparison across different JVMs, etc...
+     */
+    final int size =
+        random().nextInt(22) + 4; // ensure a reasonably large minimum number of clauses
+    final String[] terms = new String[size];
+    for (int i = 0; i < size; i++) {
+      terms[i] = Character.toString((char) ('a' + i));
+    }
+    final String expected = Arrays.stream(terms).collect(Collectors.joining(",", "or(", ")"));
+
+    /*
+    NOTE: shuffling below shouldn't matter at the moment (because the disjunction subSources are destined for a
+    HashMap, so will be reordered anyway); but it might matter if the internal implementation of
+    DisjunctionIntervalsSource changes.
+     */
+    Collections.shuffle(Arrays.asList(terms), random());
+
+    IntervalsSource source =
+        Intervals.or(
+            Arrays.stream(terms)
+                .map((term) -> Intervals.term(term))
+                .toArray((sz) -> new IntervalsSource[sz]));
+    assertEquals(expected, source.toString());
+  }
+
   public void testIntervalDisjunction() throws IOException {
     IntervalsSource source =
         Intervals.or(Intervals.term("pease"), Intervals.term("hot"), Intervals.term("notMatching"));