Beispiel #1
0
Pckbuckettable *gt_pckbuckettable_new(const FMindex *fmindex,
                                      unsigned int numofchars,
                                      unsigned long totallength,
                                      unsigned int maxdepth)
{
  GtArrayPckbck_Boundsatdepth stack;
  Pckbck_Boundsatdepth parent, child;
  unsigned long rangesize, idx, *rangeOccs;
  Pckbuckettable *pckbt;
  Mbtab *tmpmbtab;

  GT_INITARRAY(&stack,Pckbck_Boundsatdepth);
  child.lowerbound = 0;
  child.upperbound = totallength+1;
  child.depth = 0;
  child.code = (GtCodetype) 0;
  GT_STOREINARRAY(&stack,Pckbck_Boundsatdepth,128,child);
  rangeOccs = gt_malloc(sizeof (*rangeOccs) * GT_MULT2(numofchars));
  tmpmbtab = gt_malloc(sizeof (*tmpmbtab) * numofchars);
  pckbt = pckbuckettable_allocandinittable(numofchars,maxdepth,true);
  while (stack.nextfreePckbck_Boundsatdepth > 0)
  {
    parent
      = stack.spacePckbck_Boundsatdepth[--stack.nextfreePckbck_Boundsatdepth];
    gt_assert(parent.lowerbound < parent.upperbound);
    rangesize = gt_bwtrangesplitallwithoutspecial(tmpmbtab,
                                                  rangeOccs,
                                                  fmindex,
                                                  parent.lowerbound,
                                                  parent.upperbound);
    gt_assert(rangesize <= (unsigned long) numofchars);
    for (idx = 0; idx < rangesize; idx++)
    {
      child.lowerbound = tmpmbtab[idx].lowerbound;
      child.upperbound = tmpmbtab[idx].upperbound;
      child.depth = parent.depth + 1;
      gt_assert(child.depth <= maxdepth);
      child.code = parent.code * numofchars + idx;
      pckbuckettable_storeBoundsatdepth(pckbt,&child);
      if (child.depth < maxdepth)
      {
        if (child.lowerbound + 1 < child.upperbound)
        {
          GT_STOREINARRAY(&stack,Pckbck_Boundsatdepth,128,child);
        } else
        {
          pckbuckettable_followleafedge(pckbt,fmindex,&child);
        }
      }
    }
  }
  GT_FREEARRAY(&stack,Pckbck_Boundsatdepth);
  gt_free(rangeOccs);
  gt_free(tmpmbtab);
  printf("filled: %lu (%.2f)\n",pckbt->numofvalues,
                        (double) pckbt->numofvalues/pckbt->maxnumofvalues);
  return pckbt;
}
static void visit_count_children(const FMindex *index,
                           Nodecount *parent,
                           GtStackNodecount *stack,
                           Mbtab *tmpmbtab,
                           GtUword *rangeOccs,
                           GT_UNUSED unsigned int numofchars)
{
  GtUword rangesize, idx, num_special;
  unsigned int offset;
  Nodecount child;

  gt_assert(parent->lower < parent->upper);
  rangesize = gt_bwtrangesplitallwithoutspecial(tmpmbtab,
                                             rangeOccs,
                                             index,
                                             parent->lower,
                                             parent->upper);
  gt_assert(rangesize <= (GtUword) numofchars);

  offset = 0U;
  num_special = parent->upper - parent->lower;
  for (idx = 0; idx < rangesize; idx++)
  {
    child.lower = tmpmbtab[idx].lowerbound;
    child.upper = tmpmbtab[idx].upperbound;
    child.leaves = 0UL;
    child.branching = 1UL;
    child.parentOffset = offset + 1U;
    child.visited = false;
    child.on_branch = false;

    /* check if child is part of a branch */
    if (child.upper - child.lower == parent->upper - parent->lower)
    {
      /* TODO DW do sth with non branching nodes */
      child.on_branch = true;
      parent->branching--;
      GT_STACK_PUSH(stack, child);
      num_special = 0UL;
      offset++;
    }
    else
    {
      /* we found a leave on parent*/
      if (child.lower + 1 == child.upper)
      {
        parent->leaves++;
        num_special--;
      }
      else
        /* child is a branch of parent node */
      {
        if (child.lower == child.upper)
        {
          /* do nothing, this is no node, this is a missing char */
        }
        else
        {
          GT_STACK_PUSH(stack, child);
          offset++;
          num_special -= (child.upper - child.lower);
        }
      }
    }
  }
  parent->leaves += num_special;
}