jpayne@68: package sketch; jpayne@68: jpayne@68: import java.util.ArrayList; jpayne@68: import java.util.concurrent.atomic.AtomicInteger; jpayne@68: import java.util.concurrent.atomic.AtomicLong; jpayne@68: jpayne@68: import kmer.AbstractKmerTable; jpayne@68: import kmer.HashBuffer; jpayne@68: import kmer.KmerTableSet; jpayne@68: import shared.Shared; jpayne@68: import shared.Timer; jpayne@68: import shared.Tools; jpayne@68: import structures.AbstractBitSet; jpayne@68: import structures.IntHashMap; jpayne@68: import structures.IntHashSetList; jpayne@68: import structures.IntList; jpayne@68: jpayne@68: public class SketchIndex extends SketchObject { jpayne@68: jpayne@68: public SketchIndex(ArrayList refs){ jpayne@68: refSketches=refs; jpayne@68: tables=new KmerTableSet(new String[] {"ways="+WAYS, "tabletype="+AbstractKmerTable.ARRAYHF, "prealloc="+(prealloc>0 ? ""+prealloc : "f")}, jpayne@68: 20+(defaultParams.trackCounts() ? 4 : 0)+18);//An extra 18 bytes per kmer because a lot of them occur multiple times jpayne@68: tables.allocateTables(); jpayne@68: tableArray=tables.tables(); jpayne@68: } jpayne@68: jpayne@68: public void load(){ jpayne@68: spawnIndexThreads(); jpayne@68: if(useWhitelist){ jpayne@68: assert(!Whitelist.exists()); jpayne@68: Whitelist.initialize(tableArray); jpayne@68: } jpayne@68: } jpayne@68: jpayne@68: /** Spawn index threads */ jpayne@68: private void spawnIndexThreads(){ jpayne@68: jpayne@68: //Do anything necessary prior to processing jpayne@68: jpayne@68: //Determine how many threads may be used jpayne@68: final int threads=Shared.threads(); jpayne@68: ArrayList alht=new ArrayList(threads); jpayne@68: AtomicInteger ai=new AtomicInteger(0); jpayne@68: AtomicLong totalKeys=new AtomicLong(0); jpayne@68: AtomicLong uniqueKeys=new AtomicLong(0); jpayne@68: for(int i=0; i=minFakeID){return false;} jpayne@68: taxID=taxtree.getIdAtLevelExtended(taxID, taxLevelExtended); jpayne@68: return taxSet.add(taxID); jpayne@68: } jpayne@68: jpayne@68: public SketchResults getSketchesList(final Sketch a, DisplayParams params){ jpayne@68: final int minHits=params.minHits, contamLevel=params.contamLevel(); jpayne@68: final boolean countContamHits=params.needContamCounts();//, metaFilter=params.hasMetaFilters(), taxFilter=params.hasTaxFilters(); jpayne@68: final Timer t=(printTime ? new Timer() : null); jpayne@68: jpayne@68: final int[] singleton=new int[1]; jpayne@68: final IntList idList=new IntList(Tools.min(targetSketchSize, indexLimit, 1000)); jpayne@68: AbstractBitSet abs=a.indexBitSet(); jpayne@68: assert((abs==null)!=countContamHits); jpayne@68: jpayne@68: final IntHashSetList taxSet; jpayne@68: final int[][] taxHits; jpayne@68: if(contamLevel>=0){ jpayne@68: taxSet=new IntHashSetList(31); jpayne@68: taxHits=new int[a.length()][]; jpayne@68: assert(taxtree!=null) : "A TaxTree is required for this operation."; jpayne@68: }else{ jpayne@68: taxSet=null; jpayne@68: taxHits=null; jpayne@68: } jpayne@68: jpayne@68: for(int i=0; i=0){ jpayne@68: int incr=0; jpayne@68: for(int id : ids){ jpayne@68: if(id>=0){ jpayne@68: final int trueID=id-1;//Minimum id is 1, indicating sketch 0. jpayne@68: idList.add(trueID);//Minimum id is 1, indicating sketch 0. jpayne@68: incr++; jpayne@68: if(taxSet!=null){addToTaxSet(trueID, taxSet, contamLevel);} jpayne@68: } jpayne@68: } jpayne@68: if(countContamHits && incr>0){abs.increment(i, incr);} jpayne@68: if(taxSet!=null && taxSet.size()>0){ jpayne@68: taxHits[i]=taxSet.toArray(); jpayne@68: taxSet.clear(); jpayne@68: } jpayne@68: } jpayne@68: jpayne@68: } jpayne@68: jpayne@68: // assert(abs!=null); jpayne@68: // assert(false) : abs.cardinality(); jpayne@68: jpayne@68: if(printTime){ jpayne@68: t.stop("\nTime for searching index: \t"); jpayne@68: t.start(); jpayne@68: } jpayne@68: jpayne@68: // System.err.println("idList.size:"+idList.size); jpayne@68: if(idList.size list=new ArrayList(Tools.min(8, idList.size)); jpayne@68: jpayne@68: int last=-1; jpayne@68: int hits=0; jpayne@68: for(int i=0; i-1 && (hits>=minHits)){ jpayne@68: final Sketch ref=refSketches.get(last); jpayne@68: list.add(ref); jpayne@68: } jpayne@68: last=id; jpayne@68: hits=0; jpayne@68: } jpayne@68: } jpayne@68: if(last>-1 && (hits>=minHits)){ jpayne@68: final Sketch ref=refSketches.get(last); jpayne@68: // if((!metaFilter || ref.passesMeta(params)) && (!taxFilter || params.passesFilter(ref))){list.add(ref);} jpayne@68: list.add(ref); jpayne@68: } jpayne@68: if(printTime){ jpayne@68: t.stop("Time for fetching sketches: \t"); jpayne@68: } jpayne@68: return list.isEmpty() ? new SketchResults(a) : new SketchResults(a, list, taxHits); jpayne@68: } jpayne@68: jpayne@68: // static ThreadLocal intMapHolder=new ThreadLocal(); jpayne@68: jpayne@68: public final int[] getSketchIdsMap(long key, int[] singleton){ jpayne@68: AbstractKmerTable set=tableArray[(int)(key%WAYS)]; jpayne@68: final int[] ids=set.getValues(key, singleton); jpayne@68: return ids; jpayne@68: } jpayne@68: jpayne@68: public SketchResults getSketchesMap(final Sketch a, DisplayParams params){ jpayne@68: final int minHits=params.minHits, contamLevel=params.contamLevel(); jpayne@68: final boolean countContamHits=params.needContamCounts();//, metaFilter=params.hasMetaFilters(), taxFilter=params.hasTaxFilters(); jpayne@68: final Timer t=(printTime ? new Timer() : null); jpayne@68: final int[] singleton=new int[1]; jpayne@68: jpayne@68: final IntHashMap idMap=new IntHashMap(Tools.min(targetSketchSize, indexLimit, intMapSize), 0.7f); jpayne@68: jpayne@68: AbstractBitSet abs=a.indexBitSet(); jpayne@68: assert((abs==null)!=countContamHits); jpayne@68: jpayne@68: final IntHashSetList taxSet; jpayne@68: final int[][] taxHits; jpayne@68: if(contamLevel>=0){ jpayne@68: taxSet=new IntHashSetList(31); jpayne@68: taxHits=new int[a.length()][]; jpayne@68: assert(taxtree!=null) : "A TaxTree is required for this operation."; jpayne@68: }else{ jpayne@68: taxSet=null; jpayne@68: taxHits=null; jpayne@68: } jpayne@68: // assert(false) : (taxHits==null)+", "+contamLevel; jpayne@68: jpayne@68: if(printTime){ jpayne@68: t.stop("\nTime for allocation: \t"); jpayne@68: t.start(); jpayne@68: } jpayne@68: jpayne@68: int[] refHitCounts; jpayne@68: if(params.printRefHits){ jpayne@68: refHitCounts=new int[a.keys.length]; jpayne@68: a.setRefHitCounts(refHitCounts); jpayne@68: }else{refHitCounts=null;} jpayne@68: jpayne@68: for(int i=0; i=0){ jpayne@68: int incr=0; jpayne@68: for(int id : ids){ jpayne@68: if(id>=0){ jpayne@68: final int trueID=id-1;//Minimum id is 1, indicating sketch 0. jpayne@68: idMap.increment(trueID); jpayne@68: if(!allToAll || compareSelf){incr++;} jpayne@68: if(taxSet!=null){addToTaxSet(trueID, taxSet, contamLevel);} jpayne@68: if(refHitCounts!=null && trueID!=a.sketchID){refHitCounts[i]++;} jpayne@68: } jpayne@68: } jpayne@68: if(countContamHits && incr>0){abs.increment(i, incr);} jpayne@68: if(taxSet!=null && taxSet.size()>0){ jpayne@68: taxHits[i]=taxSet.toArray(); jpayne@68: taxSet.clear(); jpayne@68: } jpayne@68: } jpayne@68: } jpayne@68: jpayne@68: if(printTime){ jpayne@68: t.stop("Time for searching index: \t"); jpayne@68: System.err.println("Size: \t"+idMap.size()); jpayne@68: t.start(); jpayne@68: } jpayne@68: jpayne@68: // System.err.println("idList.size:"+idList.size); jpayne@68: final int size=idMap.size(); jpayne@68: if(size==0){return new SketchResults(a);}//null breaks some things jpayne@68: jpayne@68: ArrayList list=new ArrayList(Tools.min(8, size)); jpayne@68: jpayne@68: final int[] keys=idMap.keys(); jpayne@68: final int[] values=idMap.values(); jpayne@68: jpayne@68: for(int i=0; i=minHits){ jpayne@68: int id=keys[i]; jpayne@68: final Sketch ref=refSketches.get(id); jpayne@68: // if((!metaFilter || ref.passesMeta(params)) && (!taxFilter || params.passesFilter(ref))){list.add(ref);} jpayne@68: list.add(ref); jpayne@68: } jpayne@68: } jpayne@68: if(printTime){ jpayne@68: t.stop("Time for fetching sketches: \t"); jpayne@68: } jpayne@68: return list.isEmpty() ? new SketchResults(a) : new SketchResults(a, list, taxHits); jpayne@68: } jpayne@68: jpayne@68: /*--------------------------------------------------------------*/ jpayne@68: jpayne@68: public class IndexThread extends Thread { jpayne@68: jpayne@68: public IndexThread(AtomicInteger nextIndex_, AtomicLong keyCount_, AtomicLong uniqueKeyCount_){ jpayne@68: buffer=new HashBuffer(tableArray, 1000, 31, true, false); jpayne@68: nextIndex=nextIndex_; jpayne@68: keyCount=keyCount_; jpayne@68: uniqueKeyCount=uniqueKeyCount_; jpayne@68: } jpayne@68: jpayne@68: @Override jpayne@68: public void run(){ jpayne@68: // System.err.println("Thread running."); jpayne@68: int id=nextIndex.getAndIncrement(); jpayne@68: final int numSketches=refSketches.size(); jpayne@68: final int limit0=Tools.min((AUTOSIZE || AUTOSIZE_LINEAR ? Integer.MAX_VALUE : targetSketchSize), indexLimit); jpayne@68: // System.err.println("numSketches="+numSketches); jpayne@68: while(id