New version based on sort them merge algorithm
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@180 60f365c0-8329-0410-b2a4-ec073aeeaa1d
This commit is contained in:
144
src/libecoprimer/merge.c
Normal file
144
src/libecoprimer/merge.c
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* merge.c
|
||||
*
|
||||
* Created on: 11 nov. 2008
|
||||
* Author: coissac
|
||||
*/
|
||||
|
||||
#include "ecoprimer.h"
|
||||
|
||||
static pmerge_t mergeInit(pmerge_t merge,pwordcount_t data,uint32_t s1,uint32_t s2);
|
||||
|
||||
|
||||
static pmerge_t mergeInit(pmerge_t merge, pwordcount_t data,uint32_t s1,uint32_t s2)
|
||||
{
|
||||
merge->words = data->words;
|
||||
merge->count = data->strictcount;
|
||||
merge->write = 0;
|
||||
merge->read1 = 0;
|
||||
merge->read2 = s1;
|
||||
merge->size = s1+s2;
|
||||
return merge;
|
||||
}
|
||||
|
||||
|
||||
typedef enum {S1=1,S2=2,STACK=3} source_t;
|
||||
|
||||
void ecomerge(pwordcount_t data,uint32_t s1,uint32_t s2,uint32_t remainingSeq,uint32_t seqQuorum)
|
||||
{
|
||||
merge_t merged;
|
||||
source_t source;
|
||||
word_t currentword,tmpword;
|
||||
uint32_t currentcount,tmpcount;
|
||||
int same;
|
||||
queue_t queue;
|
||||
int nsame=0;
|
||||
uint32_t maxcount=0;
|
||||
bool_t writed=TRUE;
|
||||
|
||||
// DEBUG_LOG("Coucou %p s1= %d s2= %d",data,s1,s2)
|
||||
|
||||
(void)mergeInit(&merged,data,s1,s2);
|
||||
(void)newQueue(&queue,MINI(s1,s2));
|
||||
|
||||
while (merged.read1 < s1 && merged.read2 < merged.size)
|
||||
{
|
||||
if (! queue.empty)
|
||||
{
|
||||
currentword = queue.words[queue.pop];
|
||||
currentcount = queue.count[queue.pop];
|
||||
source=STACK;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentword = merged.words[merged.read1];
|
||||
currentcount = merged.count[merged.read1];
|
||||
source=S1;
|
||||
}
|
||||
|
||||
if (WORD(currentword) > WORD(merged.words[merged.read2]))
|
||||
{
|
||||
currentword = merged.words[merged.read2];
|
||||
currentcount = merged.count[merged.read2];
|
||||
source = S2;
|
||||
}
|
||||
|
||||
same = (source != S2) && (WORD(currentword) == WORD(merged.words[merged.read2]));
|
||||
nsame+=same;
|
||||
|
||||
// DEBUG_LOG("Merging : r1 = %d s1 = %d r2 = %d size = %d word = %s source=%u same=%u",merged.read1,s1,merged.read2-s1,merged.size,ecoUnhashWord(currentword,18),source,same)
|
||||
|
||||
tmpword = merged.words[merged.write];
|
||||
tmpcount= merged.count[merged.write];
|
||||
|
||||
merged.words[merged.write] = currentword;
|
||||
merged.count[merged.write] = currentcount;
|
||||
|
||||
if (source != S2)
|
||||
{
|
||||
if (same)
|
||||
{
|
||||
merged.count[merged.write]+=merged.count[merged.read2];
|
||||
|
||||
if (ISMULTIWORD(currentword) || ISMULTIWORD(merged.words[merged.read2]))
|
||||
merged.words[merged.write]=SETMULTIWORD(currentword);
|
||||
|
||||
merged.read2++;
|
||||
}
|
||||
|
||||
if (source==STACK)
|
||||
pop(&queue);
|
||||
merged.read1++;
|
||||
}
|
||||
else
|
||||
merged.read2++;
|
||||
|
||||
if (writed && merged.read1 <= merged.write && merged.write < s1)
|
||||
push(&queue,tmpword,tmpcount);
|
||||
|
||||
if (merged.count[merged.write] > maxcount)
|
||||
maxcount=merged.count[merged.write];
|
||||
|
||||
writed = remainingSeq + merged.count[merged.write] >= seqQuorum;
|
||||
if (writed)
|
||||
merged.write++;
|
||||
|
||||
|
||||
// else
|
||||
// DEBUG_LOG("Remove word : %s count : %d remainingSeq : %d total : %d Quorum : %d",
|
||||
// ecoUnhashWord(currentword,18),merged.count[merged.write],remainingSeq,maxcount+remainingSeq,seqQuorum);
|
||||
|
||||
} /* while loop */
|
||||
|
||||
// DEBUG_LOG("r1 : %d r2 : %d qsize : %d nsame : %d tot : %d write : %s count : %d source : %d size : %d pop : %d push : %d empty : %d",merged.read1,merged.read2-s1,qsize,nsame,qsize+nsame,ecoUnhashWord(currentword,18),currentcount,source,queue.size,queue.pop,queue.push,queue.empty)
|
||||
|
||||
|
||||
if (merged.read2 < merged.size)
|
||||
for (;merged.read2 < merged.size;merged.read2++)
|
||||
{
|
||||
merged.words[merged.write]=merged.words[merged.read2];
|
||||
merged.count[merged.write]=merged.count[merged.read2];
|
||||
if (remainingSeq + merged.count[merged.write] >= seqQuorum)
|
||||
merged.write++;
|
||||
|
||||
}
|
||||
else while (! queue.empty)
|
||||
{
|
||||
// DEBUG_LOG("write : %s count : %d write : %d size : %d pop : %d push : %d empty : %d",ecoUnhashWord(queue.words[queue.pop],18),queue.count[queue.pop],merged.write,queue.size,queue.pop,queue.push,queue.empty)
|
||||
merged.words[merged.write]=queue.words[queue.pop];
|
||||
merged.count[merged.write]=queue.count[queue.pop];
|
||||
pop(&queue);
|
||||
if (remainingSeq + merged.count[merged.write] >= seqQuorum)
|
||||
merged.write++;
|
||||
}
|
||||
|
||||
data->size = merged.write;
|
||||
|
||||
cleanQueue(&queue);
|
||||
|
||||
// DEBUG_LOG("Max count : %d remainingSeq : %d total : %d Quorum : %d",maxcount,remainingSeq,maxcount+remainingSeq,seqQuorum)
|
||||
// DEBUG_LOG("Second word : %s",ecoUnhashWord(data->words[1],18))
|
||||
// DEBUG_LOG("Last word : %s",ecoUnhashWord(data->words[data->size-1],18))
|
||||
|
||||
|
||||
}
|
Reference in New Issue
Block a user