From 70a7363f7621d78b1a970d0c53493cc32a6f3cfa Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Wed, 5 Aug 2020 00:53:27 +0300 Subject: [PATCH] some features in main.cpp fastest Variant implementation --- lib/main/containers/picontainers.cpp | 3 + lib/main/containers/pimap.h | 7 + lib/main/core/pibase.h | 2 +- lib/main/core/pistring.h | 10 + main.cpp | 337 +++++++++++++++++++-------- 5 files changed, 262 insertions(+), 97 deletions(-) diff --git a/lib/main/containers/picontainers.cpp b/lib/main/containers/picontainers.cpp index 41ba1fb2..a6533554 100644 --- a/lib/main/containers/picontainers.cpp +++ b/lib/main/containers/picontainers.cpp @@ -371,4 +371,7 @@ * \fn bool PIMapIterator::next() * \brief Jump to next entry and return if new position is valid. +* \fn void PIMapIterator::reset() +* \brief Reset iterator to initial position. + * */ diff --git a/lib/main/containers/pimap.h b/lib/main/containers/pimap.h index 47f0d3b7..ea71ead1 100644 --- a/lib/main/containers/pimap.h +++ b/lib/main/containers/pimap.h @@ -364,6 +364,13 @@ public: } return false; } + inline void reset() { + if (rev) { + pos = m.size_s(); + } else { + pos = -1; + } + } private: const MapType & m; ssize_t pos; diff --git a/lib/main/core/pibase.h b/lib/main/core/pibase.h index e0b1dd0a..7d31d3c8 100644 --- a/lib/main/core/pibase.h +++ b/lib/main/core/pibase.h @@ -467,7 +467,7 @@ uint letobe_i(uint v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF #endif -/// \brief Generic hash function, impements murmur3/32 algorithm +/// \brief Generic hash function, implements murmur3/32 algorithm inline uint piHashData(const uchar * data, uint len, uint seed = 0) { if (!data || len <= 0) return 0u; uint h = seed; diff --git a/lib/main/core/pistring.h b/lib/main/core/pistring.h index 9268f759..6c166521 100644 --- a/lib/main/core/pistring.h +++ b/lib/main/core/pistring.h @@ -337,6 +337,16 @@ public: * \sa \a expandRightTo() */ PIString & expandLeftTo(const int len, const PIChar c) {if (len > length()) insert(0, PIString(len - length(), c)); return *this;} + /*! \brief Enlarge and returns copy of this string to length "len" + * by addition sequence of symbols "c" at the end of string + * \sa \a expandRightTo() */ + PIString expandedRightTo(const int len, const PIChar c) const {return PIString(*this).expandRightTo(len, c);} + + /*! \brief Enlarge and returns copy of this string to length "len" + * by addition sequence of symbols "c" at the beginning of string + * \sa \a expandLeftTo() */ + PIString expandedLeftTo(const int len, const PIChar c) const {return PIString(*this).expandLeftTo(len, c);} + /*! \brief Add "c" symbols at the beginning and end of the string, and return this string * \sa \a quoted() */ PIString & quote(PIChar c = PIChar('"')) {insert(0, c); *this += c; return *this;} diff --git a/main.cpp b/main.cpp index 621a56e3..511302a7 100644 --- a/main.cpp +++ b/main.cpp @@ -1,114 +1,259 @@ #include "pip.h" -/*#ifdef PIP_LUA -#include "piluaprogram.h" -static const char * script -= "-- script.lua \n" - "test()\n" - "testString = \"LuaBridge works ававава!\" \n" - "number = 42 \n"; +PIMap results; -void test() { - piCout << "C function test"; -} - -int main() { - PILuaProgram p; - p.getGlobalNamespace().addFunction("test", test); - if (!p.load(PIString::fromUTF8(script))) piCout << "error"; - p.prepare(); - luabridge::LuaRef s = p.getGlobal("testString"); - luabridge::LuaRef n = p.getGlobal("number"); - PIString luaString = s.cast(); - int answer = n.cast(); - piCout << luaString; - piCout << "And here's our number:" << answer; -} -#else -int main() { - return 0; -} -#endif -*/ -class db { -public: - db() { - name = PIStringAscii("sflner;ljner.vjnrevsg;j35m4;gberjg2mnv"); - for (int i=0; i<10000; ++i) - x << sin(double(i)/180.0); - //printf("jkfkhg\n"); - } - PIString name; - PIVector x; +template +struct __VariantTypeInfo__ { + typedef T PureType; + typedef const T ConstPureType; + typedef T * PointerType; + typedef const T * ConstPointerType; + typedef T & ReferenceType; + typedef const T & ConstReferenceType; }; -inline PIByteArray & operator <<(PIByteArray & ba, const db & v) { - PIChunkStream cs; - cs.add(1, v.name).add(2, v.x); - ba << cs.data(); - return ba; -} -inline PIByteArray & operator >>(PIByteArray & ba, db & v) { - PIByteArray src; ba >> src; PIChunkStream cs(src); - while (!cs.atEnd()) { - switch (cs.read()) { - case 1: cs.get(v.name); break; - case 2: cs.get(v.x); break; - } +#define __TYPEINFO_SINGLE(PT, T) \ + template<> struct __PIVariantTypeInfo__ { \ + typedef PT PureType; \ + typedef const PT ConstPureType; \ + typedef PT * PointerType; \ + typedef const PT * ConstPointerType; \ + typedef PT & ReferenceType; \ + typedef const PT & ConstReferenceType; \ + }; + +#define REGISTER_VARIANT_TYPEINFO(T) \ + __TYPEINFO_SINGLE(T, T &) \ + __TYPEINFO_SINGLE(T, const T) \ + __TYPEINFO_SINGLE(T, const T &) + + + + +class __VariantFunctionsBase__ { +public: + virtual __VariantFunctionsBase__ * instance() {return 0;} + virtual PIString typeName() const {return PIString();} + virtual uint hash() const {return 0;} + virtual void newT(void *& ptr, const void * value) {;} + virtual void newNullT(void *& ptr) {;} + virtual void equalT(void *& ptr, const void * value) {;} + virtual void deleteT(void *& ptr) {;} + virtual PIByteArray toData(const void * ptr) const {return PIByteArray();} + virtual void fromData(void *& ptr, PIByteArray ba) {;} + //template static PIByteArray castHelper(PIByteArray ba) {return PIByteArray();} + //template static C castVariant(const T & v) {return C();} + static PIMap & registered() {static PIMap ret; return ret;} +}; + + +template +class __VariantFunctions__: public __VariantFunctionsBase__ { +public: + __VariantFunctionsBase__ * instance() override {static __VariantFunctions__ ret; return &ret;} + PIString typeName() const override {return PIString();} + uint hash() const override {static uint ret = typeName().hash(); return ret;} + void newT(void *& ptr, const void * value) override {ptr = (void*)(new T(*(const T*)value)); printf(" * new\n");} + void newNullT(void *& ptr) override {ptr = (void*)(new T()); printf(" * new null\n");} + void equalT(void *& ptr, const void * value) override {*(T*)ptr = *(const T*)value; printf(" * =\n");} + void deleteT(void *& ptr) override {delete (T*)(ptr); printf(" * del\n");} + PIByteArray toData(const void * ptr) const override {PIByteArray ret; ret << (*(const T* &)ptr); return ret;} + void fromData(void *& ptr, PIByteArray ba) override {ba >> *(T*)ptr;} + + template static PIByteArray castHelper(PIByteArray ba) {return PIByteArray();} + template static C castVariant(const T & v) {return C();} +}; + +class Variant { +public: + Variant() {ptr = 0; f = 0;} + Variant(const Variant & v) { + ptr = 0; + f = v.f; + if (f && v.ptr) + f->newT(ptr, v.ptr); } - return ba; -} + ~Variant() {destroy();} + + Variant & operator=(const Variant & v) { + destroy(); + f = v.f; + if (f && v.ptr) + f->newT(ptr, v.ptr); + return *this; + } + + template + void setValue(const T & v) { + if (f) { + if (isMyType()) { + f->equalT(ptr, (const void *)&v); + return; + } + } + destroy(); + f = __VariantFunctions__().instance(); + f->newT(ptr, (const void *)&v); + } + + template + T value() const { + if (!f) return T(); + if (!isMyType()) + return T(); + return *(T*)(ptr); + } + + PIByteArray save() const { + if (!ptr || !f) return PIByteArray(); + PIByteArray ret; + ret << f->hash(); + ret.append(f->toData(ptr)); + return ret; + } + + bool load(PIByteArray ba) { + if (ba.size_s() < 4) return false; + uint h(0); ba >> h; + destroy(); + f = __VariantFunctionsBase__::registered().value(h, 0); + if (!f) return false; + f->newNullT(ptr); + f->fromData(ptr, ba); + return true; + } + +//private: + template + bool isMyType() const {return f->hash() == __VariantFunctions__().instance()->hash();} + + void destroy() { + if (ptr && f) + f->deleteT(ptr); + ptr = 0; + f = 0; + } + + void * ptr; + __VariantFunctionsBase__ * f; + +}; + +int Acnt = 0; + +class A { +public: + A() {i = "constructor"; /*piCout << "A()";*/ ++Acnt;} + A(const A & a): i(a.i) {/*piCout << "copy A()";*/ ++Acnt;} + ~A() {/*piCout << "~A()";*/ --Acnt;} + A & operator =(const A & a) {i = a.i; /*piCout << "= A()";*/ return *this;} + PIString i; +}; +PIByteArray & operator <<(PIByteArray & ba, const A & v) {ba << v.i; return ba;} +PIByteArray & operator >>(PIByteArray & ba, A & v) {ba >> v.i; return ba;} + + +template <> +PIString __VariantFunctions__::typeName() const {static PIString ret("int"); return ret;} +class _VariantRegistrator_int__ { +public: + _VariantRegistrator_int__() { + __VariantFunctionsBase__ * f = __VariantFunctions__().instance(); + __VariantFunctionsBase__::registered()[f->hash()] = f; + } +}; +_VariantRegistrator_int__ __reg_int__; + +template <> +PIString __VariantFunctions__::typeName() const {static PIString ret("A"); return ret;} +class _VariantRegistrator_A__ { +public: + _VariantRegistrator_A__() { + __VariantFunctionsBase__ * f = __VariantFunctions__().instance(); + __VariantFunctionsBase__::registered()[f->hash()] = f; + } +}; +_VariantRegistrator_A__ __reg_A__; -PIEthernet eth; -#include "picodeparser.h" int main() { - //PICodeParser cp; - //cp.parseFile("SH_plugin_base.h"); + { - PIMap m; - m[1] = "one"; - m[2] = "two"; + Variant v, v2; - auto it = m.makeIterator(); - while (it.next()) { - //it.next(); - it.valueRef() << "_!"; - piCout << it.key() << it.value(); + /*{ + A a, ra; + + a.i = "main"; + v.setValue(a); + + ra = v.value(); + piCout << " 1 A.i =" << ra.i; + + a.i = "main second"; + v.setValue(a); + + ra = v.value(); + piCout << " 2 A.i =" << ra.i; + + piCout << "Acnt" << Acnt; } + piCout << "Acnt" << Acnt; - /*eth.__meta_data - piForeachC (auto & i, cp.enums) { - i. - }*/ + v2 = v; + PIString ra = v2.value(); + piCout << " 3 A.i =" << ra;*/ - /*piDebug = false; - double min = -1, max = -1, mean = 0; - const int iterations = 50; - db d, d2; - for (int i = 0; i < iterations; ++i) { - //PICodeParser cp; - PITimeMeasurer tm; - for (int j = 0; j < 100; ++j) { - PIByteArray ba; - ba << d; - } - //cp.parseFile("SH_plugin_base.h"); - double ms = tm.elapsed_m(); - if (min < 0) min = ms; - if (max < 0) max = ms; - min = piMin(min, ms); - max = piMax(max, ms); - mean += ms; + A a, ra; + + a.i = "main"; + v.setValue(a); + PIByteArray ba = v.save(); + + piCout << v2.load(ba); + piCout << v2.value().i; - PIByteArray ba; - ba << d; - d2.name.clear(); - d2.x.clear(); - ba >> d2; } - piDebug = true; - piCout << d2.name << d2.x.size_s(); - piCout << min << (mean / iterations) << max;*/ + piCout << "Acnt" << Acnt; + //__VariantFunctionsBase__ * f = __VariantFunctions__().instance(); + //piCout << f->typeName(); + //f = __VariantFunctions__().instance(); + //piCout << f->typeName(); } + +/* +template +void test_var(const char * Tname) { + piCout << Tname << "..."; + ullong cnt = 0; + PIVariant _v; + PITimeMeasurer tm1s; + while (tm1s.elapsed_m() < 500.) { + ++cnt; + for (int j = 0; j < 1000; ++j) { + PIVariant v; + v = T(); + v.setValue(T(j)); + _v = v; + } + } + PIVariant v; + results[Tname] = cnt; +} + +#define TEST_VAR(T) test_var(#T) + +int main() { + TEST_VAR(int); + TEST_VAR(float); + TEST_VAR(ullong); + TEST_VAR(PIString); + int sz = 0; + auto i = results.makeIterator(); + while (i.next()) sz = piMaxi(sz, i.key().length()); + i.reset(); + while (i.next()) + piCout << i.key().expandedLeftTo(sz, ' ') << ":" << i.value(); +} +*/