/* ukkonenSPA(i) performs phase i of Ukkonen's algorithm. This * means that we're making sure that array[0,i] (note the inclusivity!) * is a part of the current suffix tree. * * Original Description: pg. 106 of Gusfield */ private void ukkonenSPA(int i) { logger.entering("UkkonenSuffixTree", "ukkonenSPA"); logger.log(Level.FINEST, String.format("i=%d", i)); assert i >= 0; /* * SPA Step 1: * "Increment index e to i+1" * * The equivalent of Gusfield's i+1 is, in our situation, just i. * However, the coordinates are inclusive in Gusfield, * and exclusive in our case (along the tree edges). Therefore, * lastE should be updated to be i+1, exactly. */ extState.lastE = i + 1; logger.log(Level.FINEST, String.format("e=%d", extState.lastE)); /* * SPA Step 2: * "Explicitly compute successive extensions, using the SEA algorithm, * starting at j_i + 1 until reaching the first extension j* where rule3 * applies or until all extensions are done in this phase." * * extState.nextExtStart encodes the (j_i)+1 value. We start there, and * iterate forward until all extensions have been performed, or until * ukkonenSEA returns false (ukkonenSEA returns a true if rule 1 or rule 2 * applies in its extension). * * We extend until j==i, because the last extension of each phase is * the extension that *just* adds the new character into the tree. */ logger.log(Level.FINEST, String.format("jstart=%d", extState.nextExtStart)); boolean keepExtending = true; int j = extState.nextExtStart; while (keepExtending && j <= i) { if (ukkonenSEA(i, j)) { j++; // we don't want to just put in the terminal character. if (i == extState.string.length() - 1 && j == i) { keepExtending = false; } } else { keepExtending = false; } System.out.println(String.format("Phase %d, Extension %d tree: ", i, j)); print(System.out); System.out.println(); System.out.flush(); System.err.println(); System.err.flush(); } /* * SPA Step 3: * "Set j_{i+1} to j*-1, to prepare for the next phase." */ extState.nextExtStart = j; logger.log(Level.FINEST, String.format("j*=%d", extState.nextExtStart)); logger.exiting("UkkonenSuffixTree", "ukkonenSPA"); }