int32 * TextbookBoyerMooreSetup<C>::GetGoodSuffix(ArenaAllocator* allocator, const Char * pat, CharCount patLen, int skip) { // pat offset q |-> longest prefix of pat which is a proper suffix of pat[0..q] // (thanks to equivalence classes being in canonical order we only need to look at the first // character of each skip grouping in the pattern) int32* prefix = AnewArray(allocator, int32, patLen); prefix[0] = 0; int32 k = 0; for (CharCount q = 1; q < patLen; q++) { while (k > 0 && pat[k * skip] != pat[q * skip]) k = prefix[k - 1]; if (pat[k * skip] == pat[q * skip]) k++; prefix[q] = k; } // As above, but for rev(pat) int32* revPrefix = AnewArray(allocator, int32, patLen); revPrefix[0] = 0; k = 0; for (CharCount q = 1; q < patLen; q++) { while (k > 0 && pat[(patLen - k - 1) * skip] != pat[(patLen - q - 1) * skip]) k = revPrefix[k - 1]; if (pat[(patLen - k - 1) * skip] == pat[(patLen - q - 1) * skip]) k++; revPrefix[q] = k; } // pat prefix length l |-> least shift s.t. pat[0..l-1] is not mismatched int32 * goodSuffix = AnewArray(allocator, int32, patLen + 1); for (CharCount j = 0; j <= patLen; j++) goodSuffix[j] = patLen - prefix[patLen - 1]; for (CharCount l = 1; l <= patLen; l++) { CharCount j = patLen - revPrefix[l - 1]; int32 s = l - revPrefix[l - 1]; if (goodSuffix[j] > s) goodSuffix[j] = s; } // shift above one to the left for (CharCount j = 0; j < patLen; j++) goodSuffix[j] = goodSuffix[j + 1]; AdeleteArray(allocator, patLen, prefix); AdeleteArray(allocator, patLen, revPrefix); return goodSuffix; }
void TextbookBoyerMooreWithLinearMap<C>::FreeBody(ArenaAllocator* allocator, CharCount patLen) { if(goodSuffix) { AdeleteArray(allocator, patLen + 1, goodSuffix); #if DBG goodSuffix = 0; #endif } }
void RuntimeCharTrie::FreeBody(ArenaAllocator* allocator) { for (int i = 0; i < count; i++) children[i].node.FreeBody(allocator); if (count > 0) AdeleteArray(allocator, count, children); #if DBG count = 0; children = 0; #endif }
void TextbookBoyerMoore<C>::FreeBody(ArenaAllocator* allocator, CharCount patLen) { if(goodSuffix) { AdeleteArray(allocator, patLen + 1, goodSuffix); #if DBG goodSuffix = 0; #endif } lastOccurrence.FreeBody(allocator); }
void JSONScanner::BuildUnescapedString(bool shouldSkipLastCharacter) { AssertMsg(this->allocator != nullptr, "We must have built the allocator"); AssertMsg(this->currentRangeCharacterPairList != nullptr, "We must have built the currentRangeCharacterPairList"); AssertMsg(this->currentRangeCharacterPairList->Count() > 0, "We need to build the current string only because we have escaped characters"); // Step 1: Ensure the buffer has sufficient space int requiredSize = this->GetCurrentStringLen(); if (requiredSize > this->stringBufferLength) { if (this->stringBuffer) { AdeleteArray(this->allocator, this->stringBufferLength, this->stringBuffer); this->stringBuffer = nullptr; } this->stringBuffer = AnewArray(this->allocator, char16, requiredSize); this->stringBufferLength = requiredSize; } // Step 2: Copy the data to the buffer int totalCopied = 0; char16* begin_copy = this->stringBuffer; int lastCharacterIndex = this->currentRangeCharacterPairList->Count() - 1; for (int i = 0; i <= lastCharacterIndex; i++) { RangeCharacterPair data = this->currentRangeCharacterPairList->Item(i); int charactersToCopy = data.m_rangeLength; js_wmemcpy_s(begin_copy, charactersToCopy, this->inputText + data.m_rangeStart, charactersToCopy); begin_copy += charactersToCopy; totalCopied += charactersToCopy; if (i == lastCharacterIndex && shouldSkipLastCharacter) { continue; } *begin_copy = data.m_char; begin_copy++; totalCopied++; } if (totalCopied != requiredSize) { OUTPUT_TRACE_DEBUGONLY(Js::JSONPhase, _u("BuildUnescapedString(): allocated size = %d != copying size %d\n"), requiredSize, totalCopied); AssertMsg(totalCopied == requiredSize, "BuildUnescapedString(): The allocated size and copying size should match."); } OUTPUT_TRACE_DEBUGONLY(Js::JSONPhase, _u("BuildUnescapedString(): unescaped string as '%.*s'\n"), GetCurrentStringLen(), this->stringBuffer); }