package ch.unibe.scg.cc; import java.io.IOException; import java.util.Collection; import java.util.logging.Logger; import javax.inject.Inject; import ch.unibe.scg.cc.Annotations.PopularSnippets; import ch.unibe.scg.cc.Annotations.PopularSnippetsThreshold; import ch.unibe.scg.cc.Protos.Clone; import ch.unibe.scg.cc.Protos.Snippet; import ch.unibe.scg.cells.Mapper; import ch.unibe.scg.cells.OneShotIterable; import ch.unibe.scg.cells.Sink; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.io.BaseEncoding; /** Filter phase of the pipeline */ class Function2RoughCloner implements Mapper<Snippet, Clone> { final static private long serialVersionUID = 1L; final static private Logger logger = Logger.getLogger(Function2RoughCloner.class.getName()); final private Sink<Snippet> popularSnippets; final private int popularSnippetThreshold; @Inject Function2RoughCloner(@PopularSnippets Sink<Snippet> popularSnippets, @PopularSnippetsThreshold int popularSnippetThreshold) { this.popularSnippets = popularSnippets; this.popularSnippetThreshold = popularSnippetThreshold; } @Override public void map(Snippet first, OneShotIterable<Snippet> rowIterable, Sink<Clone> function2RoughClones) throws IOException, InterruptedException { // rowIterable is not guaranteed to be iterable more than once, so copy. Collection<Snippet> row = ImmutableList.copyOf(rowIterable); rowIterable = null; // Don't touch! logger.finer("Make rough clone from snippet " + BaseEncoding.base16().encode(Iterables.get(row, 0).getHash().toByteArray()).substring(0, 6)); if (row.size() <= 1) { return; // prevent processing non-recurring hashes } // special handling of popular snippets if (row.size() >= popularSnippetThreshold) { for (Snippet loc : row) { popularSnippets.write(loc); } return; } for (Snippet thisSnip : row) { for (Snippet thatSnip : row) { // save only half of the functions as row-key // full table gets reconstructed in MakeSnippet2FineClones // This *must* be the same as in CloneExpander. if (thisSnip.getFunction().asReadOnlyByteBuffer() .compareTo(thatSnip.getFunction().asReadOnlyByteBuffer()) < 0) { function2RoughClones.write( Clone.newBuilder().setThisSnippet(thisSnip).setThatSnippet(thatSnip).build()); } } } } @Override public void close() throws IOException { if (popularSnippets != null) { popularSnippets.close(); } } }