Skip to content

Commit

Permalink
Throw GraphException
Browse files Browse the repository at this point in the history
  • Loading branch information
cfournie committed Apr 30, 2023
1 parent af9bd6d commit 70eb2c2
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 49 deletions.
5 changes: 3 additions & 2 deletions lucene/core/src/java/org/apache/lucene/util/QueryBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import org.apache.lucene.search.Query;
import org.apache.lucene.search.SynonymQuery;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.util.graph.GraphException;
import org.apache.lucene.util.graph.GraphTokenStreamFiniteStrings;

/**
Expand Down Expand Up @@ -350,7 +351,7 @@ protected Query createFieldQuery(
return analyzeMultiBoolean(field, stream, operator);
}
}
} catch (IOException e) {
} catch (IOException | GraphException e) {
throw new RuntimeException("Error analyzing query text", e);
}
}
Expand Down Expand Up @@ -489,7 +490,7 @@ protected Query analyzeMultiPhrase(String field, TokenStream stream, int slop)
* query.
*/
protected Query analyzeGraphBoolean(
String field, TokenStream source, BooleanClause.Occur operator) throws IOException {
String field, TokenStream source, BooleanClause.Occur operator) throws IOException, GraphException {
source.reset();
GraphTokenStreamFiniteStrings graph = new GraphTokenStreamFiniteStrings(source);
BooleanQuery.Builder builder = new BooleanQuery.Builder();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.lucene.util.graph;

/** Thrown when graph token persing encounters an error. */
public class GraphException extends Exception {
public GraphException() {
super();
}

public GraphException(String message) {
super(message);
}

public GraphException(String message, Throwable cause) {
super(message, cause);
}

public GraphException(Throwable cause) {
super(cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ public TokenStream next() {
* Returns the articulation points (or cut vertices) of the graph:
* https://en.wikipedia.org/wiki/Biconnected_component
*/
public int[] articulationPoints() {
public int[] articulationPoints() throws GraphException {
if (det.getNumStates() == 0) {
return new int[0];
}
Expand Down Expand Up @@ -260,7 +260,7 @@ private static void articulationPointsRecurse(
int[] low,
int[] parent,
BitSet visited,
List<Integer> points) {
List<Integer> points) throws GraphException {
visited.set(state);
depth[state] = d;
low[state] = d;
Expand All @@ -275,7 +275,7 @@ private static void articulationPointsRecurse(
if (d < MAX_RECURSION_LEVEL) {
articulationPointsRecurse(a, t.dest, d + 1, depth, low, parent, visited, points);
} else {
continue;
throw new GraphException("Exceeded maximum recursion level");
}
childCount++;
if (low[t.dest] >= depth[state]) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.CancellationException;

import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
Expand Down Expand Up @@ -684,32 +686,6 @@ public void testLongTokenStreamStackOverflowError() throws Exception {
TokenStream ts = new CannedTokenStream(tokens.toArray(new Token[0]));
GraphTokenStreamFiniteStrings graph = new GraphTokenStreamFiniteStrings(ts);

Iterator<TokenStream> it = graph.getFiniteStrings();
assertTrue(it.hasNext());
it.next();
assertTrue(it.hasNext());
it.next();
assertFalse(it.hasNext());

int[] points = graph.articulationPoints(); // This will cause a java.lang.StackOverflowError
assertEquals(points[0], 1);
assertEquals(points[1], 3);
assertEquals(points.length, MAX_RECURSION_LEVEL - 2);

assertFalse(graph.hasSidePath(0));
it = graph.getFiniteStrings(0, 1);
assertTrue(it.hasNext());
assertTokenStream(it.next(), new String[] {"fast"}, new int[] {1});
assertFalse(it.hasNext());
Term[] terms = graph.getTerms("field", 0);
assertArrayEquals(terms, new Term[] {new Term("field", "fast")});

assertTrue(graph.hasSidePath(1));
it = graph.getFiniteStrings(1, 3);
assertTrue(it.hasNext());
assertTokenStream(it.next(), new String[] {"wi", "fi"}, new int[] {1, 1});
assertTrue(it.hasNext());
assertTokenStream(it.next(), new String[] {"wifi"}, new int[] {1});
assertFalse(it.hasNext());
assertThrows(GraphException.class, () -> graph.articulationPoints());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.graph.GraphException;
import org.apache.lucene.util.graph.GraphTokenStreamFiniteStrings;

/**
Expand All @@ -67,7 +68,7 @@
*/
final class IntervalBuilder {
static IntervalsSource analyzeText(CachingTokenFilter stream, int maxGaps, boolean ordered)
throws IOException {
throws IOException, GraphException {
assert stream != null;

TermToBytesRefAttribute termAtt = stream.getAttribute(TermToBytesRefAttribute.class);
Expand Down Expand Up @@ -198,7 +199,7 @@ private static IntervalsSource analyzeSynonyms(TokenStream ts, int maxGaps, bool
return combineSources(terms, maxGaps, ordered);
}

private static List<IntervalsSource> analyzeGraph(TokenStream source) throws IOException {
private static List<IntervalsSource> analyzeGraph(TokenStream source) throws IOException, GraphException {
source.reset();
GraphTokenStreamFiniteStrings graph = new GraphTokenStreamFiniteStrings(source);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.apache.lucene.util.automaton.CompiledAutomaton;
import org.apache.lucene.util.automaton.LevenshteinAutomata;
import org.apache.lucene.util.automaton.Operations;
import org.apache.lucene.util.graph.GraphException;

/**
* Factory functions for creating {@link IntervalsSource interval sources}.
Expand Down Expand Up @@ -514,10 +515,11 @@ public static IntervalsSource after(IntervalsSource source, IntervalsSource refe
* @return Returns an {@link IntervalsSource} that matches tokens acquired from analysis of {@code
* text}. Possibly an empty interval source, never {@code null}.
* @throws IOException If an I/O exception occurs.
* @throws GraphException If graph parsing fails.
*/
public static IntervalsSource analyzedText(
String text, Analyzer analyzer, String field, int maxGaps, boolean ordered)
throws IOException {
throws IOException, GraphException {
try (TokenStream ts = analyzer.tokenStream(field, text)) {
return analyzedText(ts, maxGaps, ordered);
}
Expand All @@ -535,9 +537,10 @@ public static IntervalsSource analyzedText(
* @return Returns an {@link IntervalsSource} that matches tokens acquired from analysis of {@code
* text}. Possibly an empty interval source, never {@code null}.
* @throws IOException If an I/O exception occurs.
* @throws GraphException If graph parsing fails.
*/
public static IntervalsSource analyzedText(TokenStream tokenStream, int maxGaps, boolean ordered)
throws IOException {
throws IOException, GraphException {
CachingTokenFilter stream =
tokenStream instanceof CachingTokenFilter
? (CachingTokenFilter) tokenStream
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,10 @@
import org.apache.lucene.tests.analysis.Token;
import org.apache.lucene.tests.index.RandomIndexWriter;
import org.apache.lucene.tests.util.LuceneTestCase;
import org.apache.lucene.util.graph.GraphException;

public class TestIntervalBuilder extends LuceneTestCase {
public void testSimpleTerm() throws IOException {
public void testSimpleTerm() throws IOException, GraphException {
CannedTokenStream ts = new CannedTokenStream(new Token("term1", 1, 2));

IntervalsSource source = IntervalBuilder.analyzeText(new CachingTokenFilter(ts), -1, true);
Expand All @@ -63,7 +64,7 @@ public void testSimpleTerm() throws IOException {
assertEquals(expected, source);
}

public void testOrdered() throws IOException {
public void testOrdered() throws IOException, GraphException {
CannedTokenStream ts =
new CannedTokenStream(
new Token("term1", 1, 2), new Token("term2", 3, 4), new Token("term3", 5, 6));
Expand All @@ -76,7 +77,7 @@ public void testOrdered() throws IOException {
assertEquals(expected, source);
}

public void testUnordered() throws IOException {
public void testUnordered() throws IOException, GraphException {
CannedTokenStream ts =
new CannedTokenStream(
new Token("term1", 1, 2), new Token("term2", 3, 4), new Token("term3", 5, 6));
Expand All @@ -89,7 +90,7 @@ public void testUnordered() throws IOException {
assertEquals(expected, source);
}

public void testPhrase() throws IOException {
public void testPhrase() throws IOException, GraphException {
CannedTokenStream ts =
new CannedTokenStream(
new Token("term1", 1, 2), new Token("term2", 3, 4), new Token("term3", 5, 6));
Expand All @@ -101,7 +102,7 @@ public void testPhrase() throws IOException {
assertEquals(expected, source);
}

public void testPhraseWithStopword() throws IOException {
public void testPhraseWithStopword() throws IOException, GraphException {
CannedTokenStream ts =
new CannedTokenStream(new Token("term1", 1, 1, 2), new Token("term3", 2, 5, 6));

Expand All @@ -112,13 +113,13 @@ public void testPhraseWithStopword() throws IOException {
assertEquals(expected, source);
}

public void testEmptyTokenStream() throws IOException {
public void testEmptyTokenStream() throws IOException, GraphException {
CannedTokenStream ts = new CannedTokenStream();
IntervalsSource source = IntervalBuilder.analyzeText(new CachingTokenFilter(ts), 0, true);
assertSame(IntervalBuilder.NO_INTERVALS, source);
}

public void testSimpleSynonyms() throws IOException {
public void testSimpleSynonyms() throws IOException, GraphException {
CannedTokenStream ts =
new CannedTokenStream(
new Token("term1", 1, 2),
Expand All @@ -136,7 +137,7 @@ public void testSimpleSynonyms() throws IOException {
assertEquals(expected, source);
}

public void testSimpleSynonymsWithGap() throws IOException {
public void testSimpleSynonymsWithGap() throws IOException, GraphException {
// term1 [] term2/term3/term4 term5
CannedTokenStream ts =
new CannedTokenStream(
Expand All @@ -159,7 +160,7 @@ public void testSimpleSynonymsWithGap() throws IOException {
assertEquals(expected, source);
}

public void testGraphSynonyms() throws IOException {
public void testGraphSynonyms() throws IOException, GraphException {
// term1 term2:2/term3 term4 term5
CannedTokenStream ts =
new CannedTokenStream(
Expand All @@ -179,7 +180,7 @@ public void testGraphSynonyms() throws IOException {
assertEquals(expected, source);
}

public void testGraphSynonymsWithGaps() throws IOException {
public void testGraphSynonymsWithGaps() throws IOException, GraphException {
// term1 [] term2:4/term3 [] [] term4 term5
CannedTokenStream ts =
new CannedTokenStream(
Expand All @@ -203,7 +204,7 @@ public void testGraphSynonymsWithGaps() throws IOException {
assertEquals(expected, source);
}

public void testGraphTerminatesOnGap() throws IOException {
public void testGraphTerminatesOnGap() throws IOException, GraphException {
// term1 term2:2/term3 term4 [] term5
CannedTokenStream ts =
new CannedTokenStream(
Expand All @@ -222,7 +223,7 @@ public void testGraphTerminatesOnGap() throws IOException {
assertEquals(expected, source);
}

public void testEmptyIntervals() throws IOException {
public void testEmptyIntervals() throws IOException, GraphException {
CannedTokenStream ts = new CannedTokenStream();
IntervalsSource source = IntervalBuilder.analyzeText(new CachingTokenFilter(ts), -1, true);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.queries.intervals.Intervals;
import org.apache.lucene.queries.intervals.IntervalsSource;
import org.apache.lucene.util.graph.GraphException;

/** Node that represents {@link Intervals#analyzedText(String, Analyzer, String, int, boolean)}. */
public class AnalyzedText extends IntervalFunction {
Expand All @@ -36,7 +37,7 @@ public IntervalsSource toIntervalSource(String field, Analyzer analyzer) {
boolean ordered = true;
try {
return Intervals.analyzedText(term, analyzer, field, gaps, ordered);
} catch (IOException e) {
} catch (IOException | GraphException e) {
throw new RuntimeException(e);
}
}
Expand Down

0 comments on commit 70eb2c2

Please sign in to comment.