예제 #1
0
    public void enter(File directory) {
      assert (directory.isDirectory());

      _logger.trace("enter the directory: " + directory.getName());
      File[] fileList = directory.listFiles();
      for (File file : fileList) {
        if (file.isDirectory()) {
          enter(file);
        } else {
          if (file.getName().endsWith("Track.class") && !file.getName().equals("Track.class")) {
            String className = getClassName(file);
            _logger.trace("found a track class: " + className);
            trackClassFile.add(className);
          }
          if (file.getName().endsWith("TrackGroup.class")) {
            String className = getClassName(file);
            _logger.trace("found a track group class: " + className);
            trackGroupClassFile.add(className);
          }
        }
      }
    }
예제 #2
0
  public void SAIS(LSeq SA) {

    StopWatch timer = new StopWatch();
    _logger.info("SAIS: N=" + SA.textSize());

    // Determin T[N-1]'s LS-type
    // T[i] is SType if T[i,_) < T[i+1,_)
    // T[i] is LType if T[i,_) > T[i+1,_)
    {
      long i = 0;
      for (; i < N; ++i) {
        long x = T.lookup((N + i - 1) % N);
        long y = T.lookup((N + i) % N);
        if (x == y) continue;
        if (x < y) {
          LS.set(N - 1, SType);
          break;
        } else {
          LS.set(N - 1, LType);
          break;
        }
      }
      if (i == N) {
        // When T = AAAA... , etc.
        LS.set(N - 1, LType);
      }
    }

    // T[i] is SType if T[i] < T[i+1] or T[i] = T[i+1] and T[i+1] is S-type
    // T[i] is LType if T[i] > T[i+1] or T[i] = T[i+1] and T[i+1] is L-type
    // Set the LS type of each character
    for (long i = N - 1; i > 0; --i) {
      long x = T.lookup(i);
      long y = T.lookup(i - 1);
      if (x < y) LS.set(i - 1, LType);
      else if (x > y) LS.set(i - 1, SType);
      else LS.set(i - 1, LS.get(i));
    }

    // Initialize the buckets.
    // A bucket is a container of the suffixes sharing the same first character
    {
      _logger.trace("Initialize the buckets");
      Arrays.fill(bucketEnd, 0);
      // Compute the size of each bucket
      for (long i = 0; i < N; ++i) {
        ++bucketEnd[(int) T.lookup(i)];
      }
      // Accumulate the character counts. The bucketStart holds the pointers to beginning of the
      // buckets in SA
      for (int i = 1; i < bucketEnd.length; ++i) {
        bucketEnd[i] += bucketEnd[i - 1];
      }
      _logger.trace("Done.");
    }

    // initialize the suffix array
    for (long i = 0; i < N; ++i) SA.set(i, N);

    // Step 1: reduce the problem by at least 1/2
    // Sort all the S-substrings

    // Find LMS characters
    long[] cursorInBucket = Arrays.copyOf(bucketEnd, bucketEnd.length);
    for (long i = 0; i < N; ++i) {
      if (isLMS(i)) SA.set(--cursorInBucket[(int) T.lookup(i)], i);
    }

    // Induced sorting LMS prefixes
    {
      _logger.trace(String.format("[N=%,d] induceSA", SA.textSize()));
      induceSA(SA);
      _logger.trace("Done.");
    }

    int numLMS = 0;
    // Compact all the sorted substrings into the first M items of SA
    // 2*M must be not larger than N
    for (long i = 0; i < N; ++i) {
      long si = SA.lookup(i);
      if (si != N && isLMS(si)) SA.set(numLMS++, si);
    }

    // Initialize the name array buffer
    for (long i = numLMS; i < N; ++i) SA.set(i, N);

    // Find the lexicographic names of the LMS substrings
    _logger.trace("Sorting LMS substrings: N=" + SA.textSize());
    int name = 1;
    SA.set(numLMS + (SA.lookup(0) / 2), name++);
    for (long i = 1; i < numLMS; ++i) {
      final long prev = SA.lookup(i - 1);
      final long current = SA.lookup(i);
      if (!isEqualLMSSubstring(prev, current)) {
        name++;
      }
      SA.set(numLMS + (current / 2), name - 1);
    }

    for (long i = N - 1, j = N - 1; i >= numLMS; --i) {
      if (SA.lookup(i) != N) SA.set(j--, SA.lookup(i) - 1);
    }

    // Step 2: solve the reduced problem
    // Create SA1, a view of SA[0, numLMS-1]
    _logger.trace("Solving the reduced problem: N=" + SA.textSize());
    LSeq SA1 = new ArrayWrap(SA, 0, numLMS);
    LSeq T1 = new ArrayWrap(SA, N - numLMS, numLMS);
    if (name - 1 != numLMS) {
      new CyclicSAIS(T1, name - 1).SAIS(SA1);
    } else {
      // When all LMS substrings have unique names
      for (long i = 0; i < numLMS; i++) SA1.set(T1.lookup(i), i);
    }

    // Step 3: Induce SA from SA1
    // Construct P1 using T1 buffer
    for (long i = 0, j = 0; i < N; ++i) {
      if (isLMS(i)) T1.set(j++, i); //
    }
    // Translate short name into the original index at T
    // SA1 now holds the LMS-substring indexes
    for (long i = 0; i < numLMS; ++i) {
      SA1.set(i, T1.lookup(SA1.lookup(i)));
    }

    // Step 3-1: Put all the items in SA1 into corresponding S-type buckets of SA

    // Clear SA[N1 .. N-1]
    for (long i = numLMS; i < N; ++i) {
      SA.set(i, N);
    }
    // Put SA1 contents into S-type buckets of SA
    System.arraycopy(bucketEnd, 0, cursorInBucket, 0, bucketEnd.length);
    for (int i = numLMS - 1; i >= 0; --i) {
      long si = SA1.lookup(i);
      SA.set(i, N);
      long index = --cursorInBucket[(int) T.lookup(si)];
      SA.set(index, si);
    }
    // SA.set(0, T.textSize() - 1);

    // Step 3-2, 3-3
    _logger.trace("Inducing SA from SA1: N=" + SA.textSize());
    induceSA(SA);

    _logger.info(String.format("done. %.2f sec.", timer.getElapsedTime()));
  }