Advertisement
Guest User

CSpell Minimal Example

a guest
Nov 7th, 2022
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.60 KB | Source Code | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <regex>
  5. #include <map>
  6. #include <optional>
  7. #include <set>
  8. #include <cassert>
  9. #include <chrono>
  10. #include <ctime>
  11. #include <fstream>
  12. #include <shared_mutex>
  13. #include <thread>
  14.  
  15. using namespace std;
  16.  
  17. vector<string> split(string s, const string& delimiter){
  18.     vector<string> res;
  19.  
  20.     regex rgx(delimiter);
  21.     sregex_token_iterator iter(s.begin(),s.end(),
  22.                                rgx,-1);
  23.     sregex_token_iterator end;
  24.     for ( ; iter != end; ++iter){
  25.         if (*iter != "")
  26.             res.push_back(*iter);
  27.     }
  28.  
  29.     return res;
  30. }
  31.  
  32. class TemplateCluster {
  33. public:
  34.     vector<string> logTemplate;
  35.     vector<int> logIds;
  36.  
  37.     mutable shared_mutex mutex;
  38.  
  39.     TemplateCluster(){}
  40.     TemplateCluster(vector<string> tmp, vector<int> ids)
  41.             : logTemplate(tmp), logIds(ids){}
  42.  
  43.     TemplateCluster(const TemplateCluster& other) {
  44.         lock_guard<shared_mutex> l(other.mutex);
  45.         logTemplate = other.logTemplate;
  46.         logIds = other.logIds;
  47.     }
  48.     TemplateCluster(TemplateCluster&& other)  noexcept {
  49.         lock_guard<shared_mutex> l(other.mutex);
  50.         logTemplate = other.logTemplate;
  51.         logIds = other.logIds;
  52.     }
  53.     TemplateCluster& operator=(TemplateCluster&& other)  noexcept {
  54.         lock_guard<shared_mutex> l1(this->mutex), l2(other.mutex);
  55.         swap(logTemplate, other.logTemplate);
  56.         swap(logIds, other.logIds);
  57.         return *this;
  58.     }
  59. };
  60.  
  61. class TrieNode {
  62. public:
  63.     optional<TemplateCluster> cluster;
  64.     string token;
  65.     int templateNo;
  66.     map<string , TrieNode> child;
  67.  
  68.     mutable shared_mutex mutex;
  69.  
  70.     TrieNode(){}
  71.     TrieNode(string token, int templateNo)
  72.             : token(std::move(token)), templateNo(templateNo){}
  73.  
  74.     TrieNode(const optional<TemplateCluster> &cluster,
  75.              string token,
  76.              int templateNo,
  77.              const map<string, TrieNode> &child) :
  78.              cluster(cluster), token(std::move(token)), templateNo(templateNo), child(child) {}
  79.  
  80.     TrieNode(const TrieNode& other) {
  81.         lock_guard<shared_mutex> l(other.mutex);
  82.         cluster = *other.cluster;
  83.         token = other.token;
  84.         templateNo = other.templateNo;
  85.         child = other.child;
  86.     }
  87.     TrieNode(TrieNode&& other)  noexcept {
  88.         lock_guard<shared_mutex> l(other.mutex);
  89.         swap(cluster, other.cluster);
  90.         token = other.token;
  91.         templateNo = other.templateNo;
  92.         child = other.child;
  93.     }
  94.     TrieNode& operator=(TrieNode&& other)  noexcept {
  95.         lock_guard<shared_mutex> l1(this->mutex), l2(other.mutex);
  96.         swap(cluster, other.cluster);
  97.         swap(token, other.token);
  98.         swap(templateNo, other.templateNo);
  99.         swap(child, other.child);
  100.         return *this;
  101.     }
  102.     TrieNode& operator=(const TrieNode&& other)  noexcept {
  103.         lock_guard<shared_mutex> l1(this->mutex), l2(other.mutex);
  104.         cluster = *other.cluster;
  105.         token = other.token;
  106.         templateNo = other.templateNo;
  107.         child = other.child;
  108.         return *this;
  109.     }
  110. };
  111.  
  112. class Parser{
  113. public:
  114.     vector<TemplateCluster> logClust;
  115.     TrieNode trieRoot;
  116.     float tau;
  117.     int id = 0;
  118.     mutable shared_mutex clustLock;
  119.  
  120.     Parser() : tau(.5) {}
  121.     Parser(float tau)
  122.             : tau(tau){}
  123.     Parser(vector<TemplateCluster> logClust, TrieNode trieRoot, float tau)
  124.             : logClust(logClust), trieRoot(trieRoot), tau(tau){}
  125.  
  126.     vector<string> getTemplate(vector<string> lcs, vector<string> seq) {
  127.  
  128.         vector<string> res;
  129.         if (lcs.empty())
  130.             return res;
  131.  
  132.         reverse(lcs.begin(), lcs.end());
  133.         int i = 0;
  134.         for (const string& tok : seq) {
  135.             i++;
  136.             if (tok == lcs[lcs.size() - 1]){
  137.                 res.push_back(tok);
  138.                 lcs.erase(lcs.begin() + lcs.size() - 1);
  139.             }else
  140.                 res.emplace_back("<*>");
  141.             if (lcs.empty())
  142.                 break;
  143.         }
  144.         if (i < seq.size())
  145.             res.emplace_back("<*>");
  146.         return res;
  147.     }
  148.  
  149.     void removeSeqFromPrefixTree(TrieNode& prefixTreeRoot, TemplateCluster cluster) {
  150.         printf("id: %d %s\n", id, "removeSeqFromPrefixTree");
  151.         auto parentn = &prefixTreeRoot;
  152.         vector<string> seq;
  153.         copy_if (cluster.logTemplate.begin(), cluster.logTemplate.end(),
  154.                  back_inserter(seq),
  155.                  [](const string& s){return s != "<*>";});
  156.         for (const string& tok : seq) {
  157.             if ((*parentn).child.count(tok)){
  158.                 (*parentn).mutex.lock_shared();
  159.                 auto matched = &(*parentn).child[tok];
  160.                 if ((*matched).templateNo == 1){
  161.                     (*parentn).mutex.unlock_shared();
  162.                     (*parentn).mutex.lock();
  163.                     (*parentn).child.erase(tok);
  164.                     (*parentn).mutex.unlock();
  165.                     break;
  166.                 }else {
  167.                     (*matched).templateNo--;
  168.                     auto old = parentn;
  169.                     parentn = matched;
  170.                     (*old).mutex.unlock_shared();
  171.                 }
  172.             }
  173.         }
  174.     }
  175.  
  176.     void addSeqToPrefixTree(TrieNode& prefixTreeRoot, TemplateCluster newCluster) {
  177.         printf("id: %d %s\n", id, "addSeqToPrefixTree");
  178.  
  179.         auto parentn = &prefixTreeRoot;
  180.         vector<string> seq;
  181.         copy_if (newCluster.logTemplate.begin(), newCluster.logTemplate.end(),
  182.                  back_inserter(seq),
  183.                  [](const string& s){return s != "<*>";});
  184.         for (const string& tok : seq) {
  185.             if (parentn->child.count(tok))
  186.                 parentn->child[tok].templateNo++;
  187.             else{
  188.                 (*parentn).mutex.lock();
  189.                 parentn->child.insert({tok,TrieNode(tok, 1)});
  190.                 (*parentn).mutex.unlock();
  191.             }
  192.             (*parentn).mutex.lock_shared();
  193.             auto old = parentn;
  194.             parentn = &parentn->child[tok];
  195.             (*old).mutex.unlock_shared();
  196.         }
  197.         if (!parentn->cluster.has_value()) {
  198.             (*parentn).mutex.lock();
  199.             parentn->cluster = newCluster;
  200.             (*parentn).mutex.unlock();
  201.         }
  202.     }
  203.  
  204.     vector<string> LCS(vector<string> seq1, vector<string> seq2) {
  205.  
  206.         vector<vector<int>> lengths(seq1.size()+1,vector<int>(seq2.size()+1));
  207.         for (int i = 0; i < seq1.size() ; i++){
  208.             for (int j = 0; j < seq2.size(); j++) {
  209.                 if (seq1[i] == seq2[j])
  210.                     lengths[i+1][j+1] = lengths[i][j]+1;
  211.                 else
  212.                     lengths[i+1][j+1] = max(lengths[i+1][j], lengths[i][j+1]);
  213.             }
  214.         }
  215.         vector<string> result;
  216.         auto lenOfSeq1= seq1.size();
  217.         auto lenOfSeq2 = seq2.size();
  218.         while (lenOfSeq1 != 0 && lenOfSeq2 != 0){
  219.             if (lengths[lenOfSeq1][lenOfSeq2] == lengths[lenOfSeq1-1][lenOfSeq2])
  220.                 lenOfSeq1--;
  221.             else if (lengths[lenOfSeq1][lenOfSeq2] == lengths[lenOfSeq1][lenOfSeq2-1])
  222.                 lenOfSeq2--;
  223.             else{
  224.                 assert(seq1[lenOfSeq1-1] == seq2[lenOfSeq2-1] && "Error in LCS");
  225.                 result.insert(result.begin(), seq1[lenOfSeq1-1]);
  226.                 lenOfSeq1--;
  227.                 lenOfSeq2--;
  228.             }
  229.         }
  230.         return result;
  231.     }
  232.  
  233.     optional<TemplateCluster*> LCSMatch(vector<TemplateCluster> &cluster, vector<string> logMsg) {
  234.         printf("id: %d %s\n", id, "LCSMatch");
  235.  
  236.         optional<TemplateCluster *> res;
  237.         set<string> msgSet;
  238.         for (const string& w : logMsg) {
  239.             msgSet.insert(w);
  240.         }
  241.         double msgLen = logMsg.size();
  242.         int maxLen = -1;
  243.         optional<TemplateCluster *> maxLCS;
  244.  
  245.         for (TemplateCluster& templateCluster : cluster) {
  246.             templateCluster.mutex.lock_shared();
  247.             set<string> tempSet;
  248.             for (auto w : templateCluster.logTemplate) {
  249.                 tempSet.insert(w);
  250.             }
  251.             set<string> intersect;
  252.             set_intersection(msgSet.begin(), msgSet.end(), tempSet.begin(), tempSet.end(),
  253.                              inserter(intersect, intersect.begin()));
  254.             if (intersect.size() < .5 * msgLen) {
  255.                 templateCluster.mutex.unlock_shared();
  256.                 continue;
  257.             }
  258.             auto lcs = LCS(logMsg, templateCluster.logTemplate);
  259.             int lenLcs = lcs.size();
  260.             if (lenLcs > maxLen ||
  261.                 (lenLcs == maxLen &&
  262.                  templateCluster.logTemplate.size() < (*maxLCS.value()).logTemplate.size())){
  263.                 maxLen = lenLcs;
  264.                 maxLCS = optional(&templateCluster);
  265.             }
  266.             templateCluster.mutex.unlock_shared();
  267.         }
  268.  
  269.         if (maxLen >= tau * msgLen)
  270.             res = maxLCS;
  271.  
  272.  
  273.         return res;
  274.     }
  275.  
  276.     optional<TemplateCluster*> simpleLoopMatch(vector<TemplateCluster> &cluster, vector<string> constLogMsg) {
  277.         printf("id: %d %s\n", id, "loopMatch");
  278.  
  279.         for (TemplateCluster& templateCluster : cluster) {
  280.             templateCluster.mutex.lock_shared();
  281.             if (templateCluster.logTemplate.size() < .5 * constLogMsg.size())
  282.                 continue;
  283.             set<string> tokenSet;
  284.             for (string w : constLogMsg) {
  285.                 tokenSet.insert(w);
  286.             }
  287.             if (all_of(templateCluster.logTemplate.cbegin(), templateCluster.logTemplate.cend(),
  288.                        [&tokenSet](const string &tok) { return tok == "<*>" || tokenSet.count(tok); })) {
  289.                 templateCluster.mutex.unlock_shared();
  290.                 return &templateCluster;
  291.             }
  292.             templateCluster.mutex.unlock_shared();
  293.         }
  294.         return nullopt;
  295.     }
  296.  
  297.     optional<TemplateCluster*> prefixTreeMatch(TrieNode &prefixTree, vector<string> constLogMsg, int start) {
  298.         printf("id: %d %s\n", id, "trieMatch");
  299.  
  300.         for (int i = start; i < constLogMsg.size(); i++) {
  301.             if (prefixTree.child.count(constLogMsg[i])){
  302.                 prefixTree.child.at(constLogMsg[i]).mutex.lock_shared();
  303.                 TrieNode *child = &(prefixTree.child.at(constLogMsg[i]));
  304.                 if ((*child).cluster.has_value()) {
  305.                     vector<string> tmp = (*child).cluster.value().logTemplate;
  306.                     vector<string> constLM;
  307.                     copy_if(tmp.begin(), tmp.end(),
  308.                             back_inserter(constLM),
  309.                             [](string s) { return s != "<*>"; });
  310.                     if (constLM.size() >= tau * constLogMsg.size()) {
  311.                         (*child).mutex.unlock_shared();
  312. //                        return child.cluster.has_value() ? child.cluster : nullopt;
  313.                         return &((*child).cluster.value());
  314.                     }
  315.                 } else {
  316.                     auto res = prefixTreeMatch((*child), constLogMsg, i + 1);
  317.                     (*child).mutex.unlock_shared();
  318.                     return res;
  319.                 }
  320.  
  321.                 (*child).mutex.unlock_shared();
  322.             }
  323.         }
  324.         return nullopt;
  325.     }
  326.  
  327.     vector<TemplateCluster> parse(vector<string> content, int lastLine=0, int ID=0){
  328.         printf("ID: %d start: %d.\n", ID, lastLine);
  329.  
  330.         this->id = ID;
  331.         for (auto iter = content.begin(); iter < content.end(); iter++) {
  332.             int i = distance(content.begin(), iter)+1;
  333.             printf("ID: %d line: %d.\n", ID, i);
  334.             int logID = i + lastLine;
  335.             vector<string> tokMsg = split(*iter, "[\\s=:,]");
  336.             vector<string> constLogMsg;
  337.             copy_if (tokMsg.begin(), tokMsg.end(),
  338.                      back_inserter(constLogMsg),
  339.                      [](string s){return s != "<*>";});
  340.  
  341.             optional<TemplateCluster *>  matchCluster = prefixTreeMatch(trieRoot, constLogMsg, 0);
  342.             if (!matchCluster.has_value()){
  343.                 matchCluster = simpleLoopMatch(logClust, constLogMsg);
  344.                 if (!matchCluster.has_value()){
  345.                     matchCluster = LCSMatch(logClust, tokMsg);
  346.                     if (!matchCluster.has_value()){
  347.  
  348.                         vector<int> ids = {logID};
  349.                         auto newCluster = TemplateCluster(tokMsg, ids);
  350.                         clustLock.lock();
  351.                         logClust.push_back(newCluster);
  352.                         addSeqToPrefixTree(trieRoot, newCluster);
  353.                         clustLock.unlock();
  354.                     }else{
  355.                         (*matchCluster.value()).mutex.lock_shared();
  356.                         auto matchClustTemp = (*matchCluster.value()).logTemplate;
  357.                         (*matchCluster.value()).mutex.unlock_shared();
  358.                         auto newTemplate = getTemplate(LCS(tokMsg, matchClustTemp), matchClustTemp);
  359.                         if (newTemplate != matchClustTemp){
  360.                             removeSeqFromPrefixTree(trieRoot, *matchCluster.value());
  361.                             (*matchCluster.value()).mutex.lock();
  362.                             (*matchCluster.value()).logTemplate = newTemplate;
  363.                             (*matchCluster.value()).mutex.unlock();
  364.                             addSeqToPrefixTree(trieRoot, *matchCluster.value());
  365.                         }
  366.                     }
  367.                 }
  368.             }
  369.             if (matchCluster.has_value()){
  370.  
  371.                 for (TemplateCluster& cluster : logClust) {
  372.                     cluster.mutex.lock_shared();
  373.                     if ((*matchCluster.value()).logTemplate == cluster.logTemplate) {
  374.                         cluster.mutex.unlock_shared();
  375.                         cluster.mutex.lock();
  376.                         cluster.logIds.push_back(logID);
  377.                         cluster.mutex.unlock();
  378.                         break;
  379.                     }
  380.                     cluster.mutex.unlock_shared();
  381.  
  382.                 }
  383.             }
  384.         }
  385.         return logClust;
  386.     }
  387. };
  388.  
  389. int main()
  390. {
  391.     vector<string> lines = {"PacketResponder 1 for block blk_38865049064139660 terminating",
  392.                             "PacketResponder 0 for block blk_-6952295868487656571 terminating",
  393.                             "10.251.73.220:50010 is added to blk_7128370237687728475 size 67108864"};
  394.  
  395.     auto p = Parser(.7);
  396.     int tMax = 2;
  397.  
  398.     vector<thread> threads;
  399.  
  400.     int chunk = (int)lines.size() / tMax;
  401.     for (int i = 0; i < tMax; ++i) {
  402.         int start = chunk * i;
  403.         threads.emplace_back(&Parser::parse, &p,lines, start, i);
  404.     }
  405.  
  406.     cout << "OUT" << endl;
  407. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement