From e804c69f30240773073d0ca579dc82b772add899 Mon Sep 17 00:00:00 2001 From: Bo Date: Wed, 19 Jul 2017 05:11:03 -0400 Subject: [PATCH 1/2] Add the facil.io framework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The [facil.io](http://facil.io) framework has an integrated JSON parser, which I’ve added to this amazing testing and benchmarking suit. Thanks for a great repo! 👍🏻 --- .gitmodules | 5 +- build/premake5.lua | 28 +++--- src/cjsonlibs/facil.io_all.c | 14 +++ src/tests/facil.io.cpp | 166 +++++++++++++++++++++++++++++++++++ thirdparty/facil.io | 1 + 5 files changed, 203 insertions(+), 11 deletions(-) create mode 100644 src/cjsonlibs/facil.io_all.c create mode 100644 src/tests/facil.io.cpp create mode 160000 thirdparty/facil.io diff --git a/.gitmodules b/.gitmodules index 69b71551..f8eb19b2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -121,4 +121,7 @@ url = https://github.com/stefanocasazza/ULib [submodule "thirdparty/qajson4c"] path = thirdparty/qajson4c - url = https://github.com/USESystemEngineeringBV/qajson4c.git \ No newline at end of file + url = https://github.com/USESystemEngineeringBV/qajson4c.git +[submodule "thirdparty/facil.io"] + path = thirdparty/facil.io + url = https://github.com/boazsegev/facil.io.git diff --git a/build/premake5.lua b/build/premake5.lua index 643f2811..65faf7ed 100644 --- a/build/premake5.lua +++ b/build/premake5.lua @@ -7,7 +7,7 @@ end function copyfiles(dstDir, srcWildcard) os.mkdir(dstDir) local matches = os.matchfiles(srcWildcard) - for _, f in ipairs(matches) do + for _, f in ipairs(matches) do local filename = string.match(f, ".-([^\\/]-%.?[^%.\\/]*)$") os.copyfile(f, dstDir .. "/" .. filename) end @@ -80,14 +80,14 @@ solution "benchmark" language "C++" flags { "ExtraWarnings" } defines { "__STDC_FORMAT_MACROS=1" } - + configuration "release" defines { "NDEBUG" } optimize "Full" configuration "vs*" defines { "_CRT_SECURE_NO_WARNINGS" } - + configuration "gmake" gmake_common() @@ -99,10 +99,12 @@ solution "benchmark" "../thirdparty/include/", "../thirdparty/ujson4c/3rdparty/", "../thirdparty/pjson/inc/", - "../thirdparty/udp-json-parser/" + "../thirdparty/udp-json-parser/", + "../thirdparty/facil.io/lib/facil/core/types", + "../thirdparty/facil.io/lib/facil/core/types/fiobj", } - files { + files { "../src/**.c", } @@ -126,14 +128,16 @@ solution "benchmark" "../thirdparty/jsoncons/src", "../thirdparty/ArduinoJson/include", "../thirdparty/include/jeayeson/include/dummy", - "../thirdparty/jvar/include", + "../thirdparty/jvar/include", "../thirdparty/pjson/inc", "../thirdparty/ULib/include", + "../thirdparty/facil.io/lib/facil/core/types", + "../thirdparty/facil.io/lib/facil/core/types/fiobj", } linkoptions { "../../thirdparty/ULib/src/ulib/.libs/libulib.a" } - files { + files { "../src/*.h", "../src/*.cpp", "../src/tests/*.cpp", @@ -185,6 +189,8 @@ solution "jsonstat" "../thirdparty/jvar/include", "../thirdparty/pjson/inc", "../thirdparty/ULib/include", + "../thirdparty/facil.io/lib/facil/core/types", + "../thirdparty/facil.io/lib/facil/core/types/fiobj", } configuration "release" @@ -204,10 +210,12 @@ solution "jsonstat" "../thirdparty/", "../thirdparty/include/", "../thirdparty/ujson4c/3rdparty/", - "../thirdparty/udp-json-parser/" + "../thirdparty/udp-json-parser/", + "../thirdparty/facil.io/lib/facil/core/types", + "../thirdparty/facil.io/lib/facil/core/types/fiobj", } - files { + files { "../src/**.c", } @@ -219,7 +227,7 @@ solution "jsonstat" for _, testfile in ipairs(testfiles) do project("jsonstat_" .. path.getbasename(testfile)) kind "ConsoleApp" - files { + files { "../src/jsonstat/jsonstatmain.cpp", "../src/memorystat.cpp", testfile diff --git a/src/cjsonlibs/facil.io_all.c b/src/cjsonlibs/facil.io_all.c new file mode 100644 index 00000000..5da50e7d --- /dev/null +++ b/src/cjsonlibs/facil.io_all.c @@ -0,0 +1,14 @@ +#include "../memorystat.h" +#define FIOBJ_NESTING_PROTECTION 0 +#include "facil.io/lib/facil/core/types/fiobj.h" +#include "facil.io/lib/facil/core/types/fiobj/fiobj_types.h" + +#include "facil.io/lib/facil/core/types/fiobj/fiobj_alloc.c" +#include "facil.io/lib/facil/core/types/fiobj/fiobj_ary.c" +#include "facil.io/lib/facil/core/types/fiobj/fiobj_generic.c" +#include "facil.io/lib/facil/core/types/fiobj/fiobj_hash.c" +#include "facil.io/lib/facil/core/types/fiobj/fiobj_json.c" +#include "facil.io/lib/facil/core/types/fiobj/fiobj_misc.c" +#include "facil.io/lib/facil/core/types/fiobj/fiobj_numbers.c" +#include "facil.io/lib/facil/core/types/fiobj/fiobj_str.c" +#include "facil.io/lib/facil/core/types/fiobj/fiobj_sym.c" diff --git a/src/tests/facil.io.cpp b/src/tests/facil.io.cpp new file mode 100644 index 00000000..b8a60f75 --- /dev/null +++ b/src/tests/facil.io.cpp @@ -0,0 +1,166 @@ +#include "../test.h" +#include "facil.io/lib/facil/core/types/fiobj.h" + +#include +#include + +static int GenStat_task(fiobj_s *obj, void *arg) { + Stat *s = (Stat *)arg; + switch (obj->type) { + case FIOBJ_T_NULL: + s->nullCount++; + break; + case FIOBJ_T_TRUE: + s->trueCount++; + break; + case FIOBJ_T_FALSE: + s->falseCount++; + break; + case FIOBJ_T_FLOAT: + case FIOBJ_T_NUMBER: + s->numberCount++; + break; + case FIOBJ_T_SYMBOL: + case FIOBJ_T_STRING: + s->stringCount++; + s->stringLength += fiobj_obj2cstr(obj).len; + break; + case FIOBJ_T_ARRAY: + s->elementCount += fiobj_ary_count(obj); + s->arrayCount++; + break; + case FIOBJ_T_HASH: + s->memberCount += fiobj_hash_count(obj); + s->objectCount++; + break; + case FIOBJ_T_COUPLET: + GenStat_task(fiobj_couplet2key(obj), arg); + GenStat_task(fiobj_couplet2obj(obj), arg); + break; + case FIOBJ_T_IO: + /* invalid */ + return -1; + break; + } + return 0; +} + +class FacilParseResult : public ParseResultBase { +public: + FacilParseResult() : root() {} + ~FacilParseResult() { fiobj_free(root); } + + fiobj_s *root; +}; + +class FacilStringResult : public StringResultBase { +public: + FacilStringResult() : str() {} + ~FacilStringResult() { fiobj_free(str); } + + virtual const char *c_str() const { return fiobj_obj2cstr(str).data; } + + fiobj_s *str; +}; + +class FacilTest : public TestBase { +public: +#if TEST_INFO + virtual const char *GetName() const { return "facil.io (C)"; } + virtual const char *GetFilename() const { return __FILE__; } +#endif + +#if TEST_PARSE + virtual ParseResultBase *Parse(const char *json, size_t length) const { + (void)length; + FacilParseResult *pr = new FacilParseResult; + fiobj_json2obj(&pr->root, json, length); + if (pr->root == nullptr) { + delete pr; + return nullptr; + } + return pr; + } +#endif + +#if TEST_STRINGIFY + virtual StringResultBase * + Stringify(const ParseResultBase *parseResult) const { + const FacilParseResult *pr = + static_cast(parseResult); + FacilStringResult *sr = new FacilStringResult; + sr->str = fiobj_obj2json(pr->root, 0); + return sr; + } +#endif + +#if TEST_PRETTIFY + /* Not supported */ + virtual StringResultBase *Prettify(const ParseResultBase *parseResult) const { + const FacilParseResult *pr = + static_cast(parseResult); + FacilStringResult *sr = new FacilStringResult; + sr->str = fiobj_obj2json(pr->root, 1); + return sr; + } +#endif + +#if TEST_STATISTICS + virtual bool Statistics(const ParseResultBase *parseResult, + Stat *stat) const { + const FacilParseResult *pr = + static_cast(parseResult); + memset(stat, 0, sizeof(Stat)); + fiobj_each2(pr->root, GenStat_task, stat); + return true; + } +#endif + +#if TEST_CONFORMANCE + virtual bool ParseDouble(const char *json, double *d) const { + fiobj_s *tmp; + fiobj_json2obj(&tmp, json, 999); + if (tmp == NULL) + return false; + if (tmp->type == FIOBJ_T_FLOAT) { + *d = fiobj_obj2float(tmp); + fiobj_free(tmp); + return true; + } + if (tmp->type == FIOBJ_T_ARRAY && fiobj_ary_entry(tmp, 0) && + fiobj_ary_entry(tmp, 0)->type == FIOBJ_T_FLOAT) { + *d = fiobj_obj2float(fiobj_ary_entry(tmp, 0)); + fiobj_free(tmp); + return true; + } + fiobj_free(tmp); + return false; + } + + virtual bool ParseString(const char *json, std::string &s) const { + fiobj_s *tmp; + fiobj_json2obj(&tmp, json, 999); + if (tmp == NULL) + return false; + + if (tmp->type == FIOBJ_T_STRING) { + s = std::string(fiobj_obj2cstr(tmp).data, fiobj_obj2cstr(tmp).len + 1); + fiobj_free(tmp); + return true; + } + if (tmp->type == FIOBJ_T_ARRAY && fiobj_ary_entry(tmp, 0) && + fiobj_ary_entry(tmp, 0)->type == FIOBJ_T_STRING) { + s = std::string(fiobj_obj2cstr(fiobj_ary_entry(tmp, 0)).data, + fiobj_obj2cstr(fiobj_ary_entry(tmp, 0)).len); + fiobj_free(tmp); + tmp = nullptr; + return true; + } + fiobj_free(tmp); + tmp = nullptr; + return false; + } +#endif +}; + +REGISTER_TEST(FacilTest); diff --git a/thirdparty/facil.io b/thirdparty/facil.io new file mode 160000 index 00000000..8f1bd113 --- /dev/null +++ b/thirdparty/facil.io @@ -0,0 +1 @@ +Subproject commit 8f1bd113ea60aec4a658a37c29ecf5630f458951 From c63e90f10d6298a47bb095468039db68940a8700 Mon Sep 17 00:00:00 2001 From: Bo Date: Fri, 21 Jul 2017 12:37:16 -0400 Subject: [PATCH 2/2] Add facil.io to README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8aa15eb4..3cf10fc3 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ AllocCount | Number of memory allocation (including `malloc`, `realloc()`, `new ## Libraries -Currently 42 libraries are successfully benchmarked. They are listed in alphabetic order: +Currently 43 libraries are successfully benchmarked. They are listed in alphabetic order: Library | Language | Version | Notes --------|----------|---------|------------------- @@ -67,6 +67,7 @@ Library | Language | Version | Notes [cJSON](https://github.com/DaveGamble/cJSON) | C | 1.5.0 | [Configuru](https://github.com/emilk/Configuru) | C++ | 2015-12-18 | gcc/clang only | [dropbox/json11](https://github.com/dropbox/json11) | C++11 | +[Facil.io](https://github.com/boazsegev/facil.io) | C | 0.5.3 | [FastJson](https://github.com/mikeando/fastjson) | C++ | | Not parsing number per se, so do it as post-process. [folly](https://github.com/facebook/folly) | C++11 | 2016.08.29.00 | Need installation | [gason](https://github.com/vivkin/gason) | C++11 |