Ejemplo n.º 1
0
short_pair*
simpleSuffixSort(const usint* sequence, uint n, uint threads)
{
  if(sequence == 0 || n == 0) { return 0; }

  skew_pair* pairs = (skew_pair*)new short_pair[n * sizeof(skew_pair) / sizeof(short_pair) + 1];
  uint* keys = new uint[n];               // In text order.
  std::vector<ss_range> unsorted;
  threads = std::max(threads, (uint)1);
  #ifdef MULTITHREAD_SUPPORT
  omp_set_num_threads(threads);
  #endif

  // Initialize pairs.
  #pragma omp parallel for schedule(static)
  for(uint i = 0; i < n; i++) { pairs[i].first = i; pairs[i].second = sequence[i]; }

  // Sort according to first character.
  parallelSort(pairs, pairs + n, skew_comparator);
  unsorted.push_back(ss_range(0, n - 1));
  uint total = setRanks(pairs, keys, n, unsorted, threads, 1);

  if(sizeof(usint) < 2 * sizeof(uint))
  {
    return prefixDoubling(packPairs(pairs, n), keys, unsorted, n, threads, total, 1);
  }
  else
  {
    return prefixTripling(pairs, keys, unsorted, n, threads, total, 1);
  }
}
Ejemplo n.º 2
0
short_pair*
prefixDoubling(short_pair* pairs, uint* keys, std::vector<ss_range>& unsorted, uint n, uint threads, uint total, uint h)
{
  // Double prefix length until sorted.
  while(total > 0)
  {
    uint chunk = std::max((size_t)1, unsorted.size() / (threads * threads));
    #pragma omp parallel for schedule(dynamic, chunk)
    for(uint i = 0; i < unsorted.size(); i++)
    {
      // Set sort keys for the current range.
      short_pair* limit = pairs + unsorted[i].second;
      for(short_pair* curr = pairs + unsorted[i].first; curr <= limit; ++curr)
      {
        curr->second = keys[curr->first + h];
      }
      sequentialSort(pairs + unsorted[i].first, pairs + unsorted[i].second + 1, key_comparator);
    }
    total = setRanks(pairs, keys, n, unsorted, threads, chunk);
    h *= 2;
//    std::cout << "Sorted with h = " << h << ", unsorted total = " << total << " (" << unsorted.size() << " ranges)" << std::endl;
  }

  #pragma omp parallel for schedule(static)
  for(uint i = 0; i < n; i++) { pairs[i].second = keys[i]; }
  delete[] keys; keys = 0;
  return pairs;
}
Ejemplo n.º 3
0
short_pair*
prefixTripling(skew_pair* pairs, uint* keys, std::vector<ss_range>& unsorted, uint n, uint threads, uint total, uint h)
{
  const usint PACK_FACTOR = sizeof(usint) * CHAR_BIT / 2;

  // Triple prefix length until sorted.
  while(total > 0)
  {
    uint chunk = std::max((size_t)1, unsorted.size() / (threads * threads));
    #pragma omp parallel for schedule(dynamic, chunk)
    for(uint i = 0; i < unsorted.size(); i++)
    {
      // Set sort keys for the current range.
      skew_pair* limit = pairs + unsorted[i].second;
      for(skew_pair* curr = pairs + unsorted[i].first; curr <= limit; ++curr)
      {
        curr->second = (usint)(keys[curr->first + h]) << PACK_FACTOR;
        if(n - h > curr->first + h) { curr->second += keys[curr->first + 2 * h]; }
      }
      sequentialSort(pairs + unsorted[i].first, pairs + unsorted[i].second + 1, skew_comparator);
    }
    total = setRanks(pairs, keys, n, unsorted, threads, chunk);
    h *= 3;
//    std::cout << "Sorted with h = " << h << ", unsorted total = " << total << " (" << unsorted.size() << " ranges)" << std::endl;
  }

  #pragma omp parallel for schedule(static)
  for(uint i = 0; i < n; i++) { pairs[i].second = keys[i]; }
  delete[] keys; keys = 0;
  return packPairs(pairs, n);
}
Ejemplo n.º 4
0
uint
initialSort(short_pair* pairs, uint* keys, std::vector<ss_range>& unsorted, uint n, uint threads, uint h)
{
  // Sort according to first h characters.
  std::cout << "initialSort(short_pair* pairs, uint* keys, std::vector<ss_range>& unsorted, uint n, uint threads, uint h)" << std::endl;
  parallelSort(pairs, pairs + n, key_comparator);
  unsorted.push_back(ss_range(0, n - 1));
  uint total = setRanks(pairs, keys, n, unsorted, threads, 1);
//  std::cout << "Sorted with h = " << h << ", unsorted total = " << total << " (" << unsorted.size() << " ranges)" << std::endl;
  std::cout << "done initialSort(short_pair* pairs, uint* keys, std::vector<ss_range>& unsorted, uint n, uint threads, uint h) -- Sorted with h = " << h << ", unsorted total = " << total << " (" << unsorted.size() << " ranges)" << std::endl;

  return total;
}
Ejemplo n.º 5
0
/* dot1_rank:
 * asp != NULL => g is root
 */
static void dot1_rank(graph_t * g, aspect_t* asp)
{
    point p;
#ifdef ALLOW_LEVELS
    attrsym_t* N_level;
#endif
    edgelabel_ranks(g);

    if (asp) {
	init_UF_size(g);
	initEdgeTypes(g);
    }

    collapse_sets(g,g);
    /*collapse_leaves(g); */
    class1(g);
    p = minmax_edges(g);
    decompose(g, 0);
    if (asp && ((GD_comp(g).size > 1)||(GD_n_cluster(g) > 0))) {
	asp->badGraph = 1;
	asp = NULL;
    }
    acyclic(g);
    if (minmax_edges2(g, p))
	decompose(g, 0);
#ifdef ALLOW_LEVELS
    if ((N_level = agattr(g,AGNODE,"level",NULL)))
	setRanks(g, N_level);
    else
#endif

    if (asp)
	rank3(g, asp);
    else
	rank1(g);

    expand_ranksets(g, asp);
    cleanup1(g);
}