Introduced utilities to gradually replace utils. (#2651)

* Replace current levenshtein with much faster implementation.
* Remove usage of alias to simplify code for VS 2013.
This commit is contained in:
lighta 2017-12-06 11:38:10 -04:00 committed by Aleos
parent 3f88826bf0
commit fd8e1fe2cd
9 changed files with 90 additions and 29 deletions

View File

@ -96,6 +96,7 @@ set( COMMON_BASE_HEADERS
"${COMMON_SOURCE_DIR}/msg_conf.h"
"${COMMON_SOURCE_DIR}/cli.h"
"${COMMON_SOURCE_DIR}/yamlwrapper.h"
"${COMMON_SOURCE_DIR}/utilities.hpp"
${LIBCONFIG_HEADERS} # needed by conf.h/showmsg.h
CACHE INTERNAL "common_base headers" )
set( COMMON_BASE_SOURCES
@ -122,6 +123,7 @@ set( COMMON_BASE_SOURCES
"${COMMON_SOURCE_DIR}/msg_conf.c"
"${COMMON_SOURCE_DIR}/cli.c"
"${COMMON_SOURCE_DIR}/yamlwrapper.cpp"
"${COMMON_SOURCE_DIR}/utilities.cpp"
${LIBCONFIG_SOURCES} # needed by conf.c/showmsg.c
CACHE INTERNAL "common_base sources" )
set( COMMON_BASE_INCLUDE_DIRS

View File

@ -1,10 +1,11 @@
#COMMON_OBJ = $(ls *.c | grep -viw sql.c | sed -e "s/\.c/\.o/g")
COMMON_OBJ = core.o socket.o timer.o db.o nullpo.o malloc.o showmsg.o strlib.o utils.o \
COMMON_OBJ = core.o socket.o timer.o db.o nullpo.o malloc.o showmsg.o strlib.o utils.o utilities.o \
grfio.o mapindex.o ers.o md5calc.o minicore.o minisocket.o minimalloc.o random.o des.o \
conf.o thread.o mutex.o raconf.o mempool.o msg_conf.o cli.o sql.o yamlwrapper.o
COMMON_DIR_OBJ = $(COMMON_OBJ:%=obj/%)
COMMON_H = $(shell ls ../common/*.h)
COMMON_H += $(shell ls ../common/*.hpp)
COMMON_AR = obj/common.a
MT19937AR_OBJ = ../../3rdparty/mt19937ar/mt19937ar.o

View File

@ -48,6 +48,7 @@
<ClInclude Include="utils.h" />
<ClInclude Include="winapi.hpp" />
<ClInclude Include="yamlwrapper.h" />
<ClInclude Include="utilities.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="cli.c" />
@ -77,6 +78,7 @@
<ClCompile Include="utils.c" />
<ClCompile Include="winapi.cpp" />
<ClCompile Include="yamlwrapper.cpp" />
<ClCompile Include="utilities.cpp" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{F8FD7B1E-8E1C-4CC3-9CD1-2E28F77B6559}</ProjectGuid>

View File

@ -98,6 +98,9 @@
<ClInclude Include="yamlwrapper.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="utilities.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="cli.c">
@ -175,5 +178,8 @@
<ClCompile Include="yamlwrapper.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="utilities.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
</Project>

63
src/common/utilities.cpp Normal file
View File

@ -0,0 +1,63 @@
#include "utilities.hpp"
#include <chrono>
#include <string>
#include <algorithm>
#include <iostream>
#include <numeric> //iota
struct cScopeTimer::sPimpl {
std::chrono::steady_clock::time_point start;
std::chrono::steady_clock::time_point end;
sPimpl()
{
start = std::chrono::steady_clock::now();
}
~sPimpl(){
end = std::chrono::steady_clock::now();
std::chrono::microseconds diff = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
std::cout << " took=" << diff.count() << "ms !\n";
}
};
cScopeTimer::cScopeTimer()
: aPimpl(new sPimpl())
{}
/**
* Calculates the Levenshtein distance of two strings.
* @author http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#C.2B.2B
* comparison test was done here http://cpp.sh/2o7w
*/
int levenshtein(const std::string &s1, const std::string &s2)
{
// To change the type this function manipulates and returns, change
// the return type and the types of the two variables below.
int s1len = static_cast<int>(s1.size());
int s2len = static_cast<int>(s2.size());
auto column_start = (decltype(s1len))1;
auto column = new decltype(s1len)[s1len + 1];
std::iota(column + column_start, column + s1len + 1, column_start);
for (auto x = column_start; x <= s2len; x++) {
column[0] = x;
auto last_diagonal = x - column_start;
for (auto y = column_start; y <= s1len; y++) {
auto old_diagonal = column[y];
auto possibilities = {
column[y] + 1,
column[y - 1] + 1,
last_diagonal + (s1[y - 1] == s2[x - 1]? 0 : 1)
};
column[y] = std::min(possibilities);
last_diagonal = old_diagonal;
}
}
auto result = column[s1len];
delete[] column;
return result;
}

13
src/common/utilities.hpp Normal file
View File

@ -0,0 +1,13 @@
#pragma once
#include <memory>
#include <string>
// Class used to perform time measurement
class cScopeTimer {
struct sPimpl; //this is to avoid long compilation time
std::unique_ptr<sPimpl> aPimpl;
cScopeTimer();
};
int levenshtein( const std::string &s1, const std::string &s2 );

View File

@ -379,28 +379,3 @@ unsigned int get_percentage(const unsigned int A, const unsigned int B)
return (unsigned int)floor(result);
}
/**
* Calculates the Levenshtein distance of two strings.
* @author http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#C
*/
int levenshtein(const char *s1, const char *s2) {
unsigned int s1len, s2len, x, y, lastdiag, olddiag, i;
unsigned int *column;
s1len = strlen(s1);
s2len = strlen(s2);
column = malloc((s1len+1) * sizeof(unsigned int));
for (y = 1; y <= s1len; y++)
column[y] = y;
for (x = 1; x <= s2len; x++) {
column[0] = x;
for (y = 1, lastdiag = x-1; y <= s1len; y++) {
olddiag = column[y];
column[y] = min(min(column[y] + 1, column[y-1] + 1), lastdiag + (s1[y-1] == s2[x-1] ? 0 : 1));
lastdiag = olddiag;
}
}
i = column[s1len];
free(column);
return i;
}

View File

@ -50,8 +50,6 @@ extern uint32 GetULong(const unsigned char* buf);
extern int32 GetLong(const unsigned char* buf);
extern float GetFloat(const unsigned char* buf);
int levenshtein(const char *s1, const char *s2);
#ifdef __cplusplus
}
#endif

View File

@ -16,6 +16,7 @@
#include "../common/socket.h"
#include "../common/strlib.h"
#include "../common/utils.h"
#include "../common/utilities.hpp"
#include "../common/conf.h"
#include "map.hpp"