Bläddra i källkod

[add] Levenshtein cache

B Thibault 9 år sedan
förälder
incheckning
0a23640df1
5 ändrade filer med 77 tillägg och 35 borttagningar
  1. 1 1
      include/curseSplitOutput.hh
  2. 17 21
      include/levenshtein.hpp
  3. 43 0
      include/levenshteinCache.hh
  4. 13 13
      src/curseSplitOutput.cpp
  5. 3 0
      src/levenshtein.cpp

+ 1 - 1
include/curseSplitOutput.hh

@@ -80,7 +80,7 @@ class CurseSplitOutput: public CurseOutput
          * currently searching pattern and its results
         **/
         std::deque<std::list<const JSonElement*> > search_result;
-        std::map<const JSonElement *, ePath> diffResult;
+        std::map<const JSonElement *, eLevenshteinOperator> diffResult;
 
         /**
          * Viewport start

+ 17 - 21
include/levenshtein.hpp

@@ -4,17 +4,10 @@
 #include <list>
 #include <limits.h>
 #include "jsonElement.hh"
+#include "levenshteinCache.hh"
 
 #define LEVENSHTEIN_SENSIBILITY (0.7f)
 
-enum ePath: char
-{
-    add = '+',
-    rem = '-',
-    mod = '!',
-    equ = '='
-};
-
 float levenshteinPercent(const std::string &a, const std::string &b);
 template<class T> float levenshteinPercent(const std::list<T *> *a, const std::list<T *> *b);
 bool levenshteinStrictCompare(const char &a, const char &b);
@@ -88,7 +81,7 @@ template<class T> float levenshteinPercent(const std::list<T *> *a, const std::l
 }
 
 template<typename SIZE, class ITERATOR, class SUBTYPE>
-static size_t _levenshteinShortestPath(std::list<ePath> &result, ITERATOR aBegin, ITERATOR aEnd, ITERATOR bBegin, ITERATOR bEnd, size_t lenA, size_t lenB)
+static size_t _levenshteinShortestPath(std::list<eLevenshteinOperator> &result, ITERATOR aBegin, ITERATOR aEnd, ITERATOR bBegin, ITERATOR bEnd, size_t lenA, size_t lenB)
 {
     const size_t initLenA = lenA;
     const size_t initLenB = lenB;
@@ -104,25 +97,25 @@ static size_t _levenshteinShortestPath(std::list<ePath> &result, ITERATOR aBegin
     if (!lenA && !lenB)
     {
         for (size_t i=0; i < initLenA; ++i)
-            result.push_back(ePath::equ);
+            result.push_back(eLevenshteinOperator::equ);
         return 0;
     }
     else if (!lenA)
     {
         size_t i;
         for (i=0; i < initLenB - lenB; ++i)
-            result.push_back(ePath::equ);
+            result.push_back(eLevenshteinOperator::equ);
         for (; i < initLenB; ++i)
-            result.push_back(ePath::rem);
+            result.push_back(eLevenshteinOperator::rem);
         return lenB;
     }
     else if (!lenB)
     {
         size_t i;
         for (i=0; i < initLenA - lenA; ++i)
-            result.push_back(ePath::equ);
+            result.push_back(eLevenshteinOperator::equ);
         for (; i < initLenA; ++i)
-            result.push_back(ePath::add);
+            result.push_back(eLevenshteinOperator::add);
         return lenA;
     }
     SIZE **matrice = _levenshteinMatrice<SIZE, ITERATOR, SUBTYPE>(aBegin, aEnd, bBegin, bEnd, lenA, lenB);
@@ -134,34 +127,37 @@ static size_t _levenshteinShortestPath(std::list<ePath> &result, ITERATOR aBegin
     {
         if (i && (!j || matrice[i][j] > matrice[i-1][j]))
         {
-            result.push_front(ePath::add);
+            result.push_front(eLevenshteinOperator::add);
             --i;
         }
         else if (j && (!i || matrice[i][j] > matrice[i][j -1]))
         {
-            result.push_front(ePath::rem);
+            result.push_front(eLevenshteinOperator::rem);
             --j;
         }
         else if (i && j)
         {
-            result.push_front(matrice[i][j] == matrice[i-1][j-1] ? ePath::equ : ePath::mod);
+            result.push_front(matrice[i][j] == matrice[i-1][j-1] ? eLevenshteinOperator::equ : eLevenshteinOperator::mod);
             --i;
             --j;
         }
         else if (i)
         {
-            result.push_front(ePath::add);
+            result.push_front(eLevenshteinOperator::add);
             --i;
         }
         else if (j)
         {
-            result.push_front(ePath::rem);
+            result.push_front(eLevenshteinOperator::rem);
             --j;
         }
     }
 
     for (i = initLenA - lenA; i; --i)
-        result.push_front(ePath::equ);
+        result.push_front(eLevenshteinOperator::equ);
+
+    //TODO
+    LevenshteinCache<JSonElement *>::instance();
 
     // Clean matrice
     for (i=0; i < lenA +1; ++i)
@@ -171,7 +167,7 @@ static size_t _levenshteinShortestPath(std::list<ePath> &result, ITERATOR aBegin
 };
 
 template<class T>
-size_t levenshteinShortestPath(std::list<ePath> &result, const std::list<T*> *a, const std::list<T *> *b)
+size_t levenshteinShortestPath(std::list<eLevenshteinOperator> &result, const std::list<T*> *a, const std::list<T *> *b)
 {
     const size_t lenA = a->size();
     const size_t lenB = b->size();

+ 43 - 0
include/levenshteinCache.hh

@@ -0,0 +1,43 @@
+#pragma once
+
+#include <map>
+#include "levenshtein.hpp"
+
+enum eLevenshteinOperator: char
+{
+    add = '+',
+    rem = '-',
+    mod = '!',
+    equ = '='
+};
+
+template<class T> class LevenshteinCache
+{
+    public:
+        ~LevenshteinCache()
+        {}
+
+        void push(const T key, const eLevenshteinOperator &value)
+        {
+            cache[key] = value;
+        }
+
+    public:
+        static LevenshteinCache<T> *instance()
+        {
+            if (LevenshteinCache<JSonElement *>::_instance)
+                return LevenshteinCache<JSonElement *>::_instance;
+            return LevenshteinCache<JSonElement *>::_instance = new LevenshteinCache<JSonElement *>();
+        }
+
+    private:
+        LevenshteinCache()
+        { }
+
+    private:
+        std::map<const T, eLevenshteinOperator> cache;
+
+    private:
+        static LevenshteinCache<T> *_instance;
+};
+

+ 13 - 13
src/curseSplitOutput.cpp

@@ -85,27 +85,27 @@ void CurseSplitOutput::computeDiff()
     }
     else
     {
-        std::list<ePath> diffList;
+        std::list<eLevenshteinOperator> diffList;
         levenshteinShortestPath<JSonElement>(diffList, a, b);
 
         JSonContainer::const_iterator it = a->cbegin();
-        for (ePath i : diffList)
+        for (eLevenshteinOperator i : diffList)
             if (it != a->cend() &&
-                    (i == ePath::equ ||
-                    i == ePath::mod ||
-                    i == ePath::add))
+                    (i == eLevenshteinOperator::equ ||
+                    i == eLevenshteinOperator::mod ||
+                    i == eLevenshteinOperator::add))
             {
                 diffResult[*it] = i;
                 it++;
             }
         it = b->cbegin();
-        for (ePath i : diffList)
+        for (eLevenshteinOperator i : diffList)
             if (it != b->cend() &&
-                    (i == ePath::equ ||
-                    i == ePath::mod ||
-                    i == ePath::rem))
+                    (i == eLevenshteinOperator::equ ||
+                    i == eLevenshteinOperator::mod ||
+                    i == eLevenshteinOperator::rem))
             {
-                diffResult[*it] = i == ePath::rem ? ePath::add : i;
+                diffResult[*it] = i == eLevenshteinOperator::rem ? eLevenshteinOperator::add : i;
                 it++;
             }
     }
@@ -665,10 +665,10 @@ const OutputFlag CurseSplitOutput::getFlag(const JSonElement *item, const JSonEl
     res.searched(std::find(search_result[selectedWin].cbegin(), search_result[selectedWin].cend(), item) != search_result[selectedWin].cend());
 
     try {
-        ePath dr = diffResult.at(item);
-        if (dr == ePath::add)
+        eLevenshteinOperator dr = diffResult.at(item);
+        if (dr == eLevenshteinOperator::add)
             res.type(OutputFlag::TYPE_STRING);
-        else if (dr == ePath::mod)
+        else if (dr == eLevenshteinOperator::mod)
             res.type(OutputFlag::TYPE_NUMBER);
     }
     catch (std::out_of_range &e) {}

+ 3 - 0
src/levenshtein.cpp

@@ -33,3 +33,6 @@ bool levenshteinStrictCompare(const JSonElement *a, const JSonElement *b)
     return *a == b;
 }
 
+template<>
+LevenshteinCache<JSonElement *> *LevenshteinCache<JSonElement *>::_instance = nullptr;
+