Skip to content

Commit

Permalink
The number of essential/relevant cycles can be exponential for some m…
Browse files Browse the repository at this point in the history
…olecules - e.g. cyclo-phanes.

We know how many there are before generating them so we can et a reasonable limit which just fails if this
limit is reached. This limit can be configured by a system property.
  • Loading branch information
johnmay authored and egonw committed Mar 9, 2024
1 parent 2af6236 commit 6350490
Showing 1 changed file with 31 additions and 4 deletions.
35 changes: 31 additions & 4 deletions base/core/src/main/java/org/openscience/cdk/graph/Cycles.java
Expand Up @@ -32,6 +32,7 @@
import org.openscience.cdk.interfaces.IRing;
import org.openscience.cdk.interfaces.IRingSet;
import org.openscience.cdk.ringsearch.RingSearch;
import org.openscience.cdk.tools.LoggingToolFactory;

import java.util.ArrayDeque;
import java.util.ArrayList;
Expand Down Expand Up @@ -90,6 +91,22 @@
*/
public final class Cycles {

private static final String CDK_MAX_RELEVANT_CYCLES_KEY = "cdk.maxRelevantCycles";
private static final long MAX_RELEVANT_CYCLES = getSystemInteger(CDK_MAX_RELEVANT_CYCLES_KEY, 512000);

private static long getSystemInteger(String key, long val) {
String prop = System.getProperty(key);
if (prop == null)
return val;
try {
return Long.parseLong(prop);
} catch (NumberFormatException ex) {
LoggingToolFactory.createLoggingTool(Cycles.class)
.error("Error - Invalid number for system property=" + key);
}
return val;
}

/** Vertex paths for each cycle. */
private final int[][] paths;

Expand Down Expand Up @@ -861,19 +878,23 @@ int[][] apply(int[][] graph, int length) {

/** {@inheritDoc} */
@Override
int[][] apply(int[][] graph, int length) {
int[][] apply(int[][] graph, int length) throws Intractable {
InitialCycles ic = InitialCycles.ofBiconnectedComponent(graph, length);
RelevantCycles rc = new RelevantCycles(ic);
return new EssentialCycles(rc, ic).paths();
numberOfCyclesCheck(rc);
EssentialCycles essentialCycles = new EssentialCycles(rc, ic);
return essentialCycles.paths();
}
},
RELEVANT {

/** {@inheritDoc} */
@Override
int[][] apply(int[][] graph, int length) {
int[][] apply(int[][] graph, int length) throws Intractable {
InitialCycles ic = InitialCycles.ofBiconnectedComponent(graph, length);
return new RelevantCycles(ic).paths();
RelevantCycles rc = new RelevantCycles(ic);
numberOfCyclesCheck(rc);
return rc.paths();
}
},
ALL {
Expand Down Expand Up @@ -1024,6 +1045,12 @@ public Cycles find(IAtomContainer molecule, int[][] graph, int length) throws In
}
}

private static void numberOfCyclesCheck(RelevantCycles rc) throws Intractable {
if (rc.size() > MAX_RELEVANT_CYCLES)
throw new Intractable("Too many relevant cycles cycles! max=" + MAX_RELEVANT_CYCLES + " was=" + rc.size() + "." +
" Increase this limit with System property -D" + CDK_MAX_RELEVANT_CYCLES_KEY + "=<num>");
}

/**
* Internal - lifts a path in a subgraph back to the original graph.
*
Expand Down

0 comments on commit 6350490

Please sign in to comment.