Skip to content

Commit

Permalink
Cache recursive entries - without the caching queries in the MACCS fi…
Browse files Browse the repository at this point in the history
…ngerprint runs a lot slower. We use guava cache builder and weak keys allow entries to be GC’d when the AtomContainer has no other reference (i.e. if we are iterating over a file).

Signed-off-by: Stephan Beisken <sbeisken@gmail.com>
Signed-off-by: Egon Willighagen <egonw@users.sourceforge.net>
  • Loading branch information
johnmay authored and egonw committed Dec 18, 2013
1 parent 77cf971 commit f237d46
Showing 1 changed file with 26 additions and 12 deletions.
Expand Up @@ -23,6 +23,9 @@
*/
package org.openscience.cdk.isomorphism.matchers.smarts;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Iterables;
import org.openscience.cdk.graph.GraphUtil;
Expand All @@ -37,6 +40,8 @@
import org.openscience.cdk.tools.ILoggingTool;
import org.openscience.cdk.tools.LoggingToolFactory;

import java.util.BitSet;

/**
* This matches recursive smarts atoms.
*
Expand All @@ -50,15 +55,33 @@ public final class RecursiveSmartsAtom extends SMARTSAtom {

/** The IQueryAtomContainer created by parsing the recursive smarts */
private final IQueryAtomContainer query;

/** Query cache. */
private final LoadingCache<IAtomContainer, BitSet> cache;

/**
* Creates a new instance
*
* @param query
*/
public RecursiveSmartsAtom(IQueryAtomContainer query) {
public RecursiveSmartsAtom(final IQueryAtomContainer query) {
super(query.getBuilder());
this.query = query;
this.cache = CacheBuilder.newBuilder()
.maximumSize(42)
.weakKeys()
.build(new CacheLoader<IAtomContainer, BitSet>() {
@Override public BitSet load(IAtomContainer target) throws Exception {
BitSet hits = new BitSet();
for (int[] mapping : FluentIterable.from(Ullmann.findSubstructure(query)
.matchAll(target))
.filter(new SmartsStereoMatch(query, target))
.filter(new ComponentGrouping(query, target))) {
hits.set(mapping[0]);
}
return hits;
}
});
}

/* (non-Javadoc)
Expand All @@ -74,16 +97,7 @@ public boolean matches(IAtom atom) {

IAtomContainer target = invariants(atom).target();

// recursive queries are not currently cached - they also be faster
// by specifying the initial mapping of (0->0) and
for (int[] mapping : FluentIterable.from(Ullmann.findSubstructure(query)
.matchAll(target))
.filter(new SmartsStereoMatch(query, target))
.filter(new ComponentGrouping(query, target))) {
if (target.getAtom(mapping[0]) == atom)
return true;
}

return false;
return cache.getUnchecked(target)
.get(target.getAtomNumber(atom));
}
}

0 comments on commit f237d46

Please sign in to comment.