#include "pilercr.h" #include "forkmer.h" void FreeIndex(int Finger[], int Pos[]) { freemem(Finger); freemem(Pos); } // Check that index is correct void CheckIndex(char *S, int Slen, const int Finger[], const int Pos[]) { int Found = 0; FOR_EACH_KMER(S, Slen, i, c) bool bFound = false; for (int j = Finger[c]; j < Finger[c+1]; ++j) { if (Pos[j] == i) { ++Found; bFound = true; break; } } if (!bFound) Quit("CheckIndex failed"); END_FOR_EACH_KMER(S, Slen, i, c) Log("CheckIndex OK, %u kmers found\n", Found); } // MakeIndex: make kmer index into S. // Index is two arrays Finger[] and Pos[]. // There is one entry in Finger for every possible kmer. // Consider a kmer with code k. Let i = Finger[k] and // j = Finger[k+1]. Then Pos[i], Pos[i+1] ... Pos[j-1] are // the locations in S where k is found. // If i = j, then the kmer is not present in S. // S [in] string to be indexed // Slen [in] number of letters in S // k [in] kmer length // *ptrFinger [out] Finger[] // *ptrPos [out] Pos[] void MakeIndex(char *S, int Slen, int **ptrFinger, int **ptrPos) { assert(k > 1); assert(Slen >= k); // ctop = number of distinct kmers = (max c) + 1, where c is code. const int ctop = pow4(k); int *Finger = all(int, ctop + 1); zero(Finger, int, ctop + 1); // KmersInS = number of kmers in S const int KmersInS = Slen - k + 1; int *Pos = all(int, KmersInS); // Set Finger[c+1] to be Count[c] = number of times kmer with // code c is found in S. int *TableBase = Finger + 1; FOR_EACH_KMER(S, Slen, i, c) ++(TableBase[c]); END_FOR_EACH_KMER(S, Slen, i, c) // Set Finger[c+1] = sum(i