From 224a1ed916de32561c2c7aff837d1c55b810e267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D0=B5=D0=BB=D0=B8=D0=BF=D0=B5=D0=BD=D0=BA=D0=BE=20?= =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD?= Date: Wed, 14 Aug 2019 12:00:33 +0000 Subject: [PATCH] git-svn-id: svn://db.shs.com.ru/pip@844 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5 --- main.cpp | 382 ++++++++++++++---- src_main/core/pibase.h | 16 + src_main/core/pibytearray.h | 8 - .../piintrospection_containers_p.cpp | 3 +- .../piintrospection_containers_p.h | 1 - 5 files changed, 323 insertions(+), 87 deletions(-) diff --git a/main.cpp b/main.cpp index e0a51bdd..43b5e9dd 100644 --- a/main.cpp +++ b/main.cpp @@ -1,88 +1,316 @@ #include "pip.h" -template +template class PIHash { + //template friend PIByteArray & operator >>(PIByteArray & s, PIHash & v); + //template friend PIByteArray & operator <<(PIByteArray & s, const PIHash & v); public: - inline PIHash() { - shift = 0; - r_size = 0; - } - inline T & operator [](size_t index) {return content[index].second;} - inline const T & operator [](size_t index) const {return content[index].second;} - inline size_t size() const {return r_size;} - inline ssize_t size_s() const {return r_size;} - inline size_t capacity() const {return content.capacity();} - inline bool isEmpty() const {return content.isEmpty();} + PIHash() {;} + PIHash(const PIHash & other) {*this = other;} + virtual ~PIHash() {;} - inline PIHash & push_back(const T & v) { - uint h = piHash(v); - add_hash(h); - int i = (h >> (32 - shift)); - if (content[i].first == 0) r_size++; - content[i] = HashPair(h, v); - //for (int i=0; i & operator =(const PIHash & other) { + if (this == &other) return *this; + clear(); + pih_content = other.pih_content; return *this; } - inline PIHash & append(const T & v) {return push_back(v);} -// inline PIVector & append(const PIVector & other) { -// assert(&other != this); -// size_t ps = piv_size; -// alloc(piv_size + other.piv_size); -// newT(piv_data + ps, other.piv_data, other.piv_size); -// return *this; -// } - inline PIHash & operator <<(const T & v) {return push_back(v);} -// inline PIVector & operator <<(const PIVector & other) {return append(other);} -private: - typedef PIPair HashPair; - void add_hash(uint nh) { - piCout << "add" << nh; - //for (int i=0; i value_type; +/* + class iterator { + friend class PIHash; + private: + iterator(const PIHash * v, ssize_t p): parent(v), pos(p) {} + const PIHash * parent; + ssize_t pos; + public: + iterator(): parent(0), pos(0) {} + const Key & key() const {return const_cast * >(parent)->_key(pos);} + T & value() {return const_cast * >(parent)->_value(pos);} + void operator ++() {++pos;} + void operator ++(int) {++pos;} + void operator --() {--pos;} + void operator --(int) {--pos;} + bool operator ==(const iterator & it) const {return (pos == it.pos);} + bool operator !=(const iterator & it) const {return (pos != it.pos);} + }; + + class reverse_iterator { + friend class PIHash; + private: + reverse_iterator(const PIHash * v, ssize_t p): parent(v), pos(p) {} + const PIHash * parent; + ssize_t pos; + public: + reverse_iterator(): parent(0), pos(0) {} + const Key & key() const {return const_cast * >(parent)->_key(pos);} + T & value() const {return const_cast * >(parent)->_value(pos);} + void operator ++() {--pos;} + void operator ++(int) {--pos;} + void operator --() {++pos;} + void operator --(int) {++pos;} + bool operator ==(const reverse_iterator & it) const {return (pos == it.pos);} + bool operator !=(const reverse_iterator & it) const {return (pos != it.pos);} + }; +*/ + class const_iterator { + friend class PIHash; + private: + const_iterator(const PIHash * v, ssize_t p): parent(v), pos(p), bpos(0) { + if (pos == 0) { + pos = -1; + nextPos(); + } } - if (shift == 0) { - shift++; - content.resize(1 << shift, HashPair(0, T())); + void nextPos() { + while (++pos < parent->pih_content.size_s()) { + if (!parent->pih_content[pos].isEmpty()) + return; + } } - int i = (nh >> (32 - shift)); - while (content[i].first != nh && content[i].first != 0) { - shift++; - i = (nh >> (32 - shift)); - content.resize(1 << shift, HashPair(0, T())); - rehash(); + const PIHash * parent; + ssize_t pos, bpos; + public: + const_iterator(): parent(0), pos(0) {} + //const value_type operator *() const {return parent->_pair(pos);} + //const value_type* operator ->() const {cval = parent->_pair(pos); return &cval;} + const Key & key() const {return const_cast * >(parent)->pih_content[pos][bpos].key;} + const T & value() const {return const_cast * >(parent)->pih_content[pos][bpos].value;} + void operator ++() { + if (pos < parent->pih_content.size_s()) { + if (bpos >= parent->pih_content[pos].size_s() - 1) { + bpos = 0; + nextPos(); + } else + ++bpos; + } else { + bpos = 0; + ++pos; + } + printf(" ++: %d %d\n", pos, bpos); } - //for (int i=0; i; + private: + const_reverse_iterator(const PIHash * v, ssize_t p): parent(v), pos(p) {} + const PIHash * parent; + ssize_t pos; + public: + const_reverse_iterator(): parent(0), pos(0) {} + const value_type operator *() const {return parent->_pair(pos);} + const value_type* operator ->() const {cval = parent->_pair(pos); return &cval;} + void operator ++() {--pos;} + void operator ++(int) {--pos;} + void operator --() {++pos;} + void operator --(int) {++pos;} + bool operator ==(const const_reverse_iterator & it) const {return (pos == it.pos);} + bool operator !=(const const_reverse_iterator & it) const {return (pos != it.pos);} + mutable value_type cval; + }; +*/ + //iterator begin() {return iterator(this, 0);} + //iterator end() {return iterator(this, size());} + const_iterator begin() const {return const_iterator(this, 0);} + const_iterator end() const {return const_iterator(this, size());} + const_iterator constBegin() const {return const_iterator(this, 0);} + const_iterator constEnd() const {return const_iterator(this, size());} + //reverse_iterator rbegin() {return reverse_iterator(this, size() - 1);} + //reverse_iterator rend() {return reverse_iterator(this, -1);} + //const_reverse_iterator rbegin() const {return const_reverse_iterator(this, size() - 1);} + //const_reverse_iterator rend() const {return const_reverse_iterator(this, -1);} + //const_reverse_iterator constRbegin() const {return const_reverse_iterator(this, size() - 1);} + //const_reverse_iterator constRend() const {return const_reverse_iterator(this, -1);} + + size_t size() const {return pih_content.size();} + int size_s() const {return pih_content.size_s();} + size_t length() const {return pih_content.size();} + size_t capacity() const {return pih_content.size();} + bool isEmpty() const {return (pih_content.size() == 0);} + + T & operator [](const Key & key) { + if (pih_content.isEmpty()) _rehash(1); + int i = _index(key); + if (i < pih_content.size_s()) { + PIVector & hv(pih_content[i]); + if (hv.size_s() == 1) { + if (hv[0].key == key) + return hv[0].value; + } + for (int j = 0; j < hv.size_s(); ++j) + if (hv[j].key == key) + return hv[j].value; + } + if (pih_content[i].size_s() >= 2) + _rehash(pih_content.size_s() * 2); + i = _index(key); + pih_content[i] << HashEntry(key); + return pih_content[i].back().value; } - void rehash() { - piCout << "rehash"; - PIVector > tmpc(content.size(), HashPair(0, T())); - for (int i=0; i> (32 - shift)); - tmpc[h] = content[i]; - piCout << i << "->" << h; - } - content.swap(tmpc); + const T operator [](const Key & key) const {return value(key);} + T & at(const Key & key) {return (*this)[key];} + const T at(const Key & key) const {return (*this)[key];} + + PIHash & operator <<(const PIHash & other) { + if (other.isEmpty()) return *this; + for (int i = 0; i < other.pih_content.size_s(); ++i) + for (int j = 0; j < other.pih_content[i].size_s(); ++j) + insert(other.pih_content[i][j].key, other.pih_content[i][j].value); + return *this; } - PIVector > content; - uint shift; - size_t r_size; + bool operator ==(const PIHash & t) const {return (pih_content == t.pih_content);} + bool operator !=(const PIHash & t) const {return (pih_content != t.pih_content);} + bool contains(const Key & key) const { + bool f(false); + _find(key, f); + return f; + } + + PIHash & reserve(size_t new_size) {_rehash(new_size); return *this;} + + PIHash & remove(const Key & key) { + int i = _index(key); + if (i >= pih_content.size_s()) return *this; + PIVector & hv(pih_content[i]); + for (int j = 0; j < hv.size_s(); ++j) + if (hv[j].key == key) { + hv.remove(j); + --j; + } + return *this; + } + PIHash & erase(const Key & key) {return remove(key);} + PIHash & clear() {pih_content.clear(); return *this;} + + void swap(PIHash & other) { + piSwapBinary > >(pih_content, other.pih_content); + } + + PIHash & insert(const Key & key, const T & value) { + (*this)[key] = value; + return *this; + } + const T value(const Key & key, const T & default_ = T()) const { + int i = _index(key); + if (i >= pih_content.size_s()) return default_; + PIVector & hv(pih_content[i]); + if (hv.size_s() == 1) { + if (hv[0].key == key) + return hv[0].value; + } + for (int j = 0; j < hv.size_s(); ++j) + if (hv[j].key == key) + return hv[j].value; + return default_; + } + PIVector values() const { + PIVector ret; + for (int i = 0; i < pih_content.size_s(); ++i) + for (int j = 0; j < pih_content[i].size_s(); ++j) + ret << pih_content[i][j].value; + return ret; + } + Key key(const T & value_, const Key & default_ = Key()) const { + for (int i = 0; i < pih_content.size_s(); ++i) + for (int j = 0; j < pih_content[i].size_s(); ++j) + if (pih_content[i][j].value == value_) + return pih_content[i][j].key; + return default_; + } + PIVector keys() const { + PIVector ret; + for (int i = 0; i < pih_content.size_s(); ++i) + for (int j = 0; j < pih_content[i].size_s(); ++j) + ret << pih_content[i][j].key; + return ret; + } + + /*void dump() { + piCout << "PIHash" << size() << "entries" << PICoutManipulators::NewLine << "content:"; + for (size_t i = 0; i < pih_content.size(); ++i) + piCout << PICoutManipulators::Tab << i << ":" << pih_content[i]; + piCout << "index:"; + for (size_t i = 0; i < pim_index.size(); ++i) + piCout << PICoutManipulators::Tab << i << ":" << pim_index[i].key << "->" << pim_index[i].index; + }*/ + +protected: + struct HashEntry { + HashEntry(Key k = Key(), const T & v = T()): key(k), value(v) {;} + Key key; + T value; + bool operator ==(const HashEntry & s) const {return key == s.key;} + bool operator !=(const HashEntry & s) const {return key != s.key;} + bool operator <(const HashEntry & s) const {return key < s.key;} + bool operator >(const HashEntry & s) const {return key > s.key;} + }; + /*template friend PIByteArray & operator >>(PIByteArray & s, PIDeque::HashEntry> & v); + template friend PIByteArray & operator <<(PIByteArray & s, const PIDeque::HashEntry> & v); + + const value_type _pair(ssize_t index) const { + if (index < 0 || index >= pim_index.size_s()) + return value_type(); + //piCout << "_pair" << index << pim_index[index].index; + return value_type(pim_index[index].key, pih_content[pim_index[index].index]); + } + Key & _key(ssize_t index) {return pim_index[index].key;} + T & _value(ssize_t index) {return pih_content[pim_index[index].index];}*/ + + inline size_t asize(size_t s) { + if (s == 0) return 0; + if (pih_content.size() + pih_content.size() >= s && pih_content.size() < s) + return pih_content.size() + pih_content.size(); + ssize_t t = 0, s_ = s - 1; + while (s_ >> t) ++t; + return (1 << t); + } + int _index(const Key & k) { + return piHash(k) % pih_content.size_s(); + } + void _rehash(int ns) { + ns = asize(ns); + if (pih_content.size_s() == ns) return; + PIVector > nhc; + nhc.resize(ns); + for (int i = 0; i < pih_content.size_s(); ++i) { + for (int j = 0; j < pih_content[i].size_s(); ++j) { + HashEntry & e(pih_content[i][j]); + int ni = piHash(e.key) % ns; + nhc[ni] << e; + } + } + pih_content.swap(nhc); + } + + PIVector > pih_content; }; -template -inline PICout operator <<(PICout s, const PIHash & v) { +template +inline PICout operator <<(PICout s, const PIHash & v) { s.space(); s.setControl(0, true); s << "{"; - for (size_t i = 0; i < v.size(); ++i) { - s << v[i]; - if (i < v.size() - 1) + bool first = true; + for (typename PIHash::const_iterator i = v.begin(); i != v.end(); ++i) { + if (!first) s << ", "; + first = false; + s << i.key() << ": " << i.value(); } s << "}"; s.restoreControl(); @@ -91,20 +319,22 @@ inline PICout operator <<(PICout s, const PIHash & v) { int main() { - PIHash v; - v << "x"; - v << "bbb"; - v << "bbc"; - v << "aaa"; - v << "123"; - v << "321"; - v << "aaa" << "bbb" << "ccc"; - piCout << v.size() << v.capacity(); + PIHash h; + h["1"] = "x"; + h["2"] = "bbb"; + h["3"] = "bbc"; + h["4"] = "aaa"; + h["5"] = "123"; + h["6"] = "321"; + h["7"] = "aaa"; + piCout << h.size() << h.capacity(); + //h.reserve(64); + piCout << h.keys() << h.values(); //piCout << (1 << 2); - PIHash v2; + /*PIHash v2; for (int i=0; i<1000; ++i) { v2 << PIString::fromNumber(randomi()); - } - piCout << v2.size() << v2.capacity(); + }*/ + piCout << h; return 0; } diff --git a/src_main/core/pibase.h b/src_main/core/pibase.h index a3da4151..3590fef5 100644 --- a/src_main/core/pibase.h +++ b/src_main/core/pibase.h @@ -500,6 +500,22 @@ inline uint piHashData(const uchar * data, uint len, uint seed = 0) { } +template inline uint piHash(const T & v) { + return 0; +} + +template<> inline uint piHash(const char & v) {return piHashData((const uchar *)&v, sizeof(v));} +template<> inline uint piHash(const uchar & v) {return piHashData((const uchar *)&v, sizeof(v));} +template<> inline uint piHash(const short & v) {return piHashData((const uchar *)&v, sizeof(v));} +template<> inline uint piHash(const ushort & v) {return piHashData((const uchar *)&v, sizeof(v));} +template<> inline uint piHash(const int & v) {return piHashData((const uchar *)&v, sizeof(v));} +template<> inline uint piHash(const uint & v) {return piHashData((const uchar *)&v, sizeof(v));} +template<> inline uint piHash(const llong & v) {return piHashData((const uchar *)&v, sizeof(v));} +template<> inline uint piHash(const ullong & v) {return piHashData((const uchar *)&v, sizeof(v));} +template<> inline uint piHash(const float & v) {return piHashData((const uchar *)&v, sizeof(v));} +template<> inline uint piHash(const double & v) {return piHashData((const uchar *)&v, sizeof(v));} +template<> inline uint piHash(const ldouble & v) {return piHashData((const uchar *)&v, sizeof(v));} + #define piRoundf piRound #define piRoundd piRound #define piFloorf piFloor diff --git a/src_main/core/pibytearray.h b/src_main/core/pibytearray.h index adf5f6d9..570a4517 100755 --- a/src_main/core/pibytearray.h +++ b/src_main/core/pibytearray.h @@ -316,14 +316,6 @@ __PIBYTEARRAY_SIMPLE_TYPE__(ldouble) __PIBYTEARRAY_SIMPLE_TYPE__(PIChar) - -template -inline uint piHash(const T & v) { - PIByteArray ba; - ba << v; - return ba.hash(); -} - template<> inline uint piHash(const PIByteArray & ba) {return ba.hash();} diff --git a/src_main/introspection/piintrospection_containers_p.cpp b/src_main/introspection/piintrospection_containers_p.cpp index 4f59bb8a..ef9dd58c 100644 --- a/src_main/introspection/piintrospection_containers_p.cpp +++ b/src_main/introspection/piintrospection_containers_p.cpp @@ -44,7 +44,6 @@ PIIntrospectionContainers::_Type::_Type() { PIIntrospectionContainers::PIIntrospectionContainers() { //printf("PIIntrospectionContainers %p\n", this); - crc = standardCRC_32(); } @@ -106,7 +105,7 @@ uint PIIntrospectionContainers::typeID(const char * tn) { if (!tn) return 0u; size_t l = strlen(tn); if (l == 0) return 0u; - return crc.calculate(tn, int(l)); + return piHashData((const uchar*)tn, int(l)); } diff --git a/src_main/introspection/piintrospection_containers_p.h b/src_main/introspection/piintrospection_containers_p.h index 535a4232..16f0ece7 100644 --- a/src_main/introspection/piintrospection_containers_p.h +++ b/src_main/introspection/piintrospection_containers_p.h @@ -61,7 +61,6 @@ public: std::map data; std::map typenames; mutable PIMutex mutex; - CRC_32 crc; }; PIByteArray & operator <<(PIByteArray & s, const PIIntrospectionContainers::TypeInfo & v);