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); } } } }
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())); }