void rootsucclocationsstree(Suffixtree *stree,ArraySimpleloc *ll) { Uint headpos, leafindex, depth, distance, node, ch, *largeptr, *nodeptr; Simpleloc *llptr; CHECKARRAYSPACE(ll,Simpleloc,stree->alphasize+1); for(ch = 0; ch <= UCHAR_MAX; ch++) { if((node = stree->rootchildren[ch]) != UNDEFINEDREFERENCE) { llptr = ll->spaceSimpleloc + ll->nextfreeSimpleloc++; if(ISLEAF(node)) { leafindex = GETLEAFINDEX(node); llptr->textpos = leafindex; llptr->remain = stree->textlen - leafindex; llptr->nextnode.toleaf = true; llptr->nextnode.address = stree->leaftab + leafindex; } else { nodeptr = stree->branchtab + GETBRANCHINDEX(node); GETBOTH(depth,headpos,nodeptr); llptr->textpos = headpos; llptr->remain = depth - 1; llptr->nextnode.toleaf = false; llptr->nextnode.address = nodeptr; } CHECKADDR(stree,llptr->nextnode); } } }
void succlocationsstree(Suffixtree *stree,bool nosentinel,Simpleloc *loc, ArraySimpleloc *ll) { Uint succdepth, succ, leafindex, distance, depth, headpos, remain, *succptr, *largeptr, *nodeptr; Simpleloc *llptr; fprintf(stderr,"succlocationsstree\n"); ll->nextfreeSimpleloc = 0; CHECKARRAYSPACE(ll,Simpleloc,stree->alphasize+1); if(loc->remain > 0) { if(nosentinel && loc->nextnode.toleaf && loc->remain <= UintConst(1)) { // at the end of leaf edge: only a\$ remains return; } llptr = ll->spaceSimpleloc + ll->nextfreeSimpleloc++; llptr->textpos = loc->textpos + 1; llptr->remain = loc->remain - 1; llptr->nextnode.address = loc->nextnode.address; llptr->nextnode.toleaf = loc->nextnode.toleaf; CHECKADDR(stree,llptr->nextnode); return; } nodeptr = loc->nextnode.address; GETONLYDEPTH(depth,nodeptr); succ = GETCHILD(nodeptr); do // traverse the list of successors { if(ISLEAF(succ)) // successor is leaf { leafindex = GETLEAFINDEX(succ); remain = stree->textlen - (depth + leafindex); if(!nosentinel || remain >= UintConst(1)) { llptr = ll->spaceSimpleloc + ll->nextfreeSimpleloc++; llptr->remain = remain; llptr->textpos = depth + leafindex; llptr->nextnode.address = stree->leaftab + leafindex; llptr->nextnode.toleaf = true; CHECKADDR(stree,llptr->nextnode); } succ = LEAFBROTHERVAL(stree->leaftab[leafindex]); } else // successor is branch node { succptr = stree->branchtab + GETBRANCHINDEX(succ); GETBOTH(succdepth,headpos,succptr); // get info for branch node llptr = ll->spaceSimpleloc + ll->nextfreeSimpleloc++; llptr->textpos = depth + headpos; llptr->remain = succdepth - depth - 1; llptr->nextnode.toleaf = false; llptr->nextnode.address = succptr; CHECKADDR(stree,llptr->nextnode); succ = GETBROTHER(succptr); } } while(!NILPTR(succ)); }
static void scanprefix(Suffixtree *stree) { Uint *nodeptr = NULL, *largeptr = NULL, leafindex, nodedepth, edgelen, node, distance = 0, prevnode, prefixlen, headposition; SYMBOL *leftborder = (SYMBOL *) NULL, tailchar, edgechar = 0; if(stree->headnodedepth == 0) { // headnode is root if(stree->tailptr == stree->sentinel) { // there is no \$-edge stree->headend = NULL; return; } tailchar = *(stree->tailptr); if((node = stree->rootchildren[(Uint) tailchar]) == 0) { stree->headend = NULL; return; } if(ISLEAF(node)) { // s.cppessor edge is leaf, compare tail and leaf edge label leftborder = stree->text + GETLEAFINDEX(node); prefixlen = 1 + taillcp(stree,leftborder+1,stree->sentinel-1); (stree->tailptr) += prefixlen; stree->headstart = leftborder; stree->headend = leftborder + (prefixlen-1); stree->insertnode = node; return; } nodeptr = stree->branchtab + GETBRANCHINDEX(node); GETBOTH(nodedepth,headposition,nodeptr); // get info for branch node leftborder = stree->text + headposition; prefixlen = 1 + taillcp(stree,leftborder+1,leftborder + nodedepth - 1); (stree->tailptr)+= prefixlen; if(nodedepth > prefixlen) { // cannot reach the s.cppessor, fall out of tree stree->headstart = leftborder; stree->headend = leftborder + (prefixlen-1); stree->insertnode = node; return; } stree->headnode = nodeptr; stree->headnodedepth = nodedepth; } while(True) { // \emph{headnode} is not the root prevnode = 0; node = GETCHILD(stree->headnode); if(stree->tailptr == stree->sentinel) { // \$-edge do { // there is no \$-edge, so find last s.cppessor, of which it becomes right brother prevnode = node; if(ISLEAF(node)) { node = LEAFBROTHERVAL(stree->leaftab[GETLEAFINDEX(node)]); } else { node = GETBROTHER(stree->branchtab + GETBRANCHINDEX(node)); } } while(!NILPTR(node)); stree->insertnode = NILBIT; stree->insertprev = prevnode; stree->headend = NULL; return; } tailchar = *(stree->tailptr); do { // find s.cppessor edge with firstchar = tailchar if(ISLEAF(node)) { // s.cppessor is leaf leafindex = GETLEAFINDEX(node); leftborder = stree->text + (stree->headnodedepth + leafindex); if((edgechar = *leftborder) >= tailchar) { // edge will not come later break; } prevnode = node; node = LEAFBROTHERVAL(stree->leaftab[leafindex]); } else { // s.cppessor is branch node nodeptr = stree->branchtab + GETBRANCHINDEX(node); GETONLYHEADPOS(headposition,nodeptr); leftborder = stree->text + (stree->headnodedepth + headposition); if((edgechar = *leftborder) >= tailchar) { // edge will not come later break; } prevnode = node; node = GETBROTHER(nodeptr); } } while(!NILPTR(node)); if(NILPTR(node) || edgechar > tailchar) { // edge not found stree->insertprev = prevnode; // new edge will become brother of this stree->headend = NULL; return; } if(ISLEAF(node)) { // correct edge is leaf edge, compare its label with tail prefixlen = 1 + taillcp(stree,leftborder+1,stree->sentinel-1); (stree->tailptr) += prefixlen; stree->headstart = leftborder; stree->headend = leftborder + (prefixlen-1); stree->insertnode = node; stree->insertprev = prevnode; return; } GETDEPTHAFTERHEADPOS(nodedepth,nodeptr); // we already know headposition edgelen = nodedepth - stree->headnodedepth; prefixlen = 1 + taillcp(stree,leftborder+1,leftborder + edgelen - 1); (stree->tailptr) += prefixlen; if(edgelen > prefixlen) { // cannot reach next node stree->headstart = leftborder; stree->headend = leftborder + (prefixlen-1); stree->insertnode = node; stree->insertprev = prevnode; return; } stree->headnode = nodeptr; stree->headnodedepth = nodedepth; } }