Skip to content

Commit

Permalink
refactoring ChoiceReplacer::DoReplacements method
Browse files Browse the repository at this point in the history
  • Loading branch information
Владимир Чиж authored and Владимир Чиж committed Aug 9, 2024
1 parent ae7bf60 commit c6680af
Showing 1 changed file with 58 additions and 66 deletions.
124 changes: 58 additions & 66 deletions srcbpatch/streamreplacer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,11 @@ class ChoiceReplacer final : public ReplacerWithNext
void DoReplacements(const char toProcess, const bool aEod) const override;

protected:
void ProcessLastCharacter(const char toProcess) const;
void ProcessCharacter(const char toProcess) const;
void MakeReplace(span<const char> target) const;
void CleanTheCache(size_t SrcMatchedLength) const;
void SavePartialReplaceIdx(size_t index) const;
/// <summary>
/// check for partial or full match of data from buffer_
/// with any of lexemes sequentially
Expand Down Expand Up @@ -258,91 +263,78 @@ class ChoiceReplacer final : public ReplacerWithNext
mutable vector<char> buffer_;
};


void ChoiceReplacer::DoReplacements(const char toProcess, const bool aEod) const
{
void ChoiceReplacer::DoReplacements(const char toProcess, const bool aEod) const{
if (nullptr == pNext_)
{
throw logic_error("Replacement chain has been broken. Communicate with maintainer");
}
if (aEod) [[unlikely]]
ProcessLastCharacter(toProcess);
else
ProcessCharacter(toProcess);
}

// no more data
if (aEod)
void ChoiceReplacer::ProcessLastCharacter(const char toProcess) const {
while (cachedAmount_ > 0)
{
while (cachedAmount_ > 0)
{
// to check if we send something or not
const size_t initialCached = cachedAmount_;

// for the rest of pairs
for (size_t i = indexOfCached_; i < rpairs_.size(); ++i)
{
auto [partial, full, length, index] = CheckMatch(i);
if (full)
{ // need to send replacement
const auto& rpair = rpairs_[index];
for (size_t q = 0; q < rpair.trg_.size(); ++q) { pNext_->DoReplacements(rpair.trg_[q], false); }

const size_t szProcessed = rpair.src_.size(); // matched source
shift_left(buffer_.data(), buffer_.data() + cachedAmount_, szProcessed);

cachedAmount_ -= szProcessed;
break;
}
}
indexOfCached_ = 0; // now count from zero only

if (initialCached == cachedAmount_)
{
// send 1 byte
pNext_->DoReplacements(buffer_.data()[0], false);
shift_left(buffer_.data(), buffer_.data() + cachedAmount_, 1);
--cachedAmount_;
bool WasFullMatch = false;
for (size_t i = indexOfCached_; i < rpairs_.size(); ++i) {
auto [IsPartialMatch, IsFullMatch, SrcMatchedLength, DestStringIdx] = CheckMatch(i);
if (IsFullMatch){
WasFullMatch = true;
MakeReplace(rpairs_[DestStringIdx].trg_);
CleanTheCache(SrcMatchedLength);
break;
}
};

pNext_->DoReplacements(toProcess, aEod); // send end of the data further
return;
} // if (aEod)
}

// No full match -> send 1 char from cache
if (!WasFullMatch)
{
MakeReplace(std::span<char> (&buffer_.front(), 1));
CleanTheCache(1);
}
}
pNext_->DoReplacements(toProcess, true);
}

// set buffer of cached at once
buffer_.data()[cachedAmount_++] = toProcess;
void ChoiceReplacer::ProcessCharacter(const char toProcess) const {
buffer_[cachedAmount_++] = toProcess;
while (cachedAmount_ > 0)
{
// for the pairs
for (size_t i = indexOfCached_; i < rpairs_.size(); ++i)
{
auto [partial, full, length, index] = CheckMatch(i);
if (full)
{ // need to send replacement
const auto& rpair = rpairs_[index]; // send target at once
for (size_t q = 0; q < rpair.trg_.size(); ++q) { pNext_->DoReplacements(rpair.trg_[q], false); }

// what if the cached index other and length is less than cached
shift_left(buffer_.data(), buffer_.data() + cachedAmount_, length);
cachedAmount_ -= length;
indexOfCached_ = 0; // start from the very first pair of the lexemes again
for (size_t i = indexOfCached_; i < rpairs_.size(); ++i) {
auto [IsPartialMatch, IsFullMatch, SrcMatchedLength, DestStringIdx] = CheckMatch(i);
if (IsFullMatch){
MakeReplace(rpairs_[DestStringIdx].trg_);
CleanTheCache(SrcMatchedLength);
return;
}

if (partial)
{
indexOfCached_ = index;
if (IsPartialMatch) {
SavePartialReplaceIdx(DestStringIdx);
return;
}
}// for (size_t i = indexOfCached_; i < rpairs_.size(); ++i)
}
// No any match -> send 1 char from cache
MakeReplace(std::span<char> (&buffer_.front(), 1));
CleanTheCache(1);
}
}

// send 1 byte
pNext_->DoReplacements(buffer_.data()[0], false);
shift_left(buffer_.data(), buffer_.data() + cachedAmount_, 1);
--cachedAmount_;
indexOfCached_ = 0; // start from the very first pair of the lexemes again
} // while (cachedAmount_ > 0)
inline void ChoiceReplacer::MakeReplace(span<const char> target) const {
for (char elem : target) {
pNext_->DoReplacements(elem, false);
}
}

// cachedAmount_ is zero - nothing to send
inline void ChoiceReplacer::CleanTheCache(size_t SrcMatchedLength) const{
shift_left(buffer_.data(), buffer_.data() + cachedAmount_, SrcMatchedLength);
cachedAmount_ -= SrcMatchedLength;
indexOfCached_ = 0;
}

inline void ChoiceReplacer::SavePartialReplaceIdx(size_t index) const{
indexOfCached_ = index;
}

namespace
{
Expand Down

0 comments on commit c6680af

Please sign in to comment.