git-svn-id: svn://db.shs.com.ru/pip@844 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5

This commit is contained in:
2019-08-14 12:00:33 +00:00
parent 6be61e2f39
commit 224a1ed916
5 changed files with 323 additions and 87 deletions

376
main.cpp
View File

@@ -1,88 +1,316 @@
#include "pip.h" #include "pip.h"
template <typename T> template <typename Key, typename T>
class PIHash { class PIHash {
//template <typename Key1, typename T1> friend PIByteArray & operator >>(PIByteArray & s, PIHash<Key1, T1> & v);
//template <typename Key1, typename T1> friend PIByteArray & operator <<(PIByteArray & s, const PIHash<Key1, T1> & v);
public: public:
inline PIHash() { PIHash() {;}
shift = 0; PIHash(const PIHash<Key, T> & other) {*this = other;}
r_size = 0; virtual ~PIHash() {;}
}
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();}
inline PIHash<T> & push_back(const T & v) { PIHash<Key, T> & operator =(const PIHash<Key, T> & other) {
uint h = piHash(v); if (this == &other) return *this;
add_hash(h); clear();
int i = (h >> (32 - shift)); pih_content = other.pih_content;
if (content[i].first == 0) r_size++;
content[i] = HashPair(h, v);
//for (int i=0; i<content.size_s(); ++i) piCout << i << content[i].first << content[i].second;
return *this; return *this;
} }
inline PIHash<T> & append(const T & v) {return push_back(v);}
// inline PIVector<T> & append(const PIVector<T> & other) { typedef T mapped_type;
// assert(&other != this); typedef Key key_type;
// size_t ps = piv_size; typedef PIPair<Key, T> value_type;
// alloc(piv_size + other.piv_size); /*
// newT(piv_data + ps, other.piv_data, other.piv_size); class iterator {
// return *this; friend class PIHash<Key, T>;
// }
inline PIHash<T> & operator <<(const T & v) {return push_back(v);}
// inline PIVector<T> & operator <<(const PIVector<T> & other) {return append(other);}
private: private:
typedef PIPair<uint, T> HashPair; iterator(const PIHash<Key, T> * v, ssize_t p): parent(v), pos(p) {}
void add_hash(uint nh) { const PIHash<Key, T> * parent;
piCout << "add" << nh; ssize_t pos;
//for (int i=0; i<content.size_s(); ++i) piCout << i << content[i].first << content[i].second; public:
if (nh == 0) { iterator(): parent(0), pos(0) {}
piCout << "invalid hash"; const Key & key() const {return const_cast<PIHash<Key, T> * >(parent)->_key(pos);}
T & value() {return const_cast<PIHash<Key, T> * >(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<Key, T>;
private:
reverse_iterator(const PIHash<Key, T> * v, ssize_t p): parent(v), pos(p) {}
const PIHash<Key, T> * parent;
ssize_t pos;
public:
reverse_iterator(): parent(0), pos(0) {}
const Key & key() const {return const_cast<PIHash<Key, T> * >(parent)->_key(pos);}
T & value() const {return const_cast<PIHash<Key, T> * >(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<Key, T>;
private:
const_iterator(const PIHash<Key, T> * v, ssize_t p): parent(v), pos(p), bpos(0) {
if (pos == 0) {
pos = -1;
nextPos();
}
}
void nextPos() {
while (++pos < parent->pih_content.size_s()) {
if (!parent->pih_content[pos].isEmpty())
return; return;
} }
if (shift == 0) {
shift++;
content.resize(1 << shift, HashPair(0, T()));
} }
int i = (nh >> (32 - shift)); const PIHash<Key, T> * parent;
while (content[i].first != nh && content[i].first != 0) { ssize_t pos, bpos;
shift++; public:
i = (nh >> (32 - shift)); const_iterator(): parent(0), pos(0) {}
content.resize(1 << shift, HashPair(0, T())); //const value_type operator *() const {return parent->_pair(pos);}
rehash(); //const value_type* operator ->() const {cval = parent->_pair(pos); return &cval;}
const Key & key() const {return const_cast<PIHash<Key, T> * >(parent)->pih_content[pos][bpos].key;}
const T & value() const {return const_cast<PIHash<Key, T> * >(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;
} }
//for (int i=0; i<content.size_s(); ++i) piCout << i << content[i].first << content[i].second; printf(" ++: %d %d\n", pos, bpos);
} }
void rehash() { //void operator ++(int) {++pos;}
piCout << "rehash"; void operator --() {
PIVector<PIPair<uint, T> > tmpc(content.size(), HashPair(0, T())); --pos;
for (int i=0; i<content.size_s(); ++i) {
if (content[i].first == 0) continue;
int h = (content[i].first >> (32 - shift));
tmpc[h] = content[i];
piCout << i << "->" << h;
} }
content.swap(tmpc); //void operator --(int) {--pos;}
bool operator ==(const const_iterator & it) const {return (pos == it.pos && bpos == it.bpos);}
bool operator !=(const const_iterator & it) const {return !(*this == it);}
mutable value_type cval;
};
/*
class const_reverse_iterator {
friend class PIHash<Key, T>;
private:
const_reverse_iterator(const PIHash<Key, T> * v, ssize_t p): parent(v), pos(p) {}
const PIHash<Key, T> * 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<HashEntry> & 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;
}
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<Key, T> & operator <<(const PIHash<Key, T> & 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<PIPair<uint, T> > content; bool operator ==(const PIHash<Key, T> & t) const {return (pih_content == t.pih_content);}
uint shift; bool operator !=(const PIHash<Key, T> & t) const {return (pih_content != t.pih_content);}
size_t r_size; bool contains(const Key & key) const {
bool f(false);
_find(key, f);
return f;
}
PIHash<Key, T> & reserve(size_t new_size) {_rehash(new_size); return *this;}
PIHash<Key, T> & remove(const Key & key) {
int i = _index(key);
if (i >= pih_content.size_s()) return *this;
PIVector<HashEntry> & 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<Key, T> & erase(const Key & key) {return remove(key);}
PIHash<Key, T> & clear() {pih_content.clear(); return *this;}
void swap(PIHash<Key, T> & other) {
piSwapBinary<PIVector<PIVector<HashEntry> > >(pih_content, other.pih_content);
}
PIHash<Key, T> & 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<HashEntry> & 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<T> values() const {
PIVector<T> 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<Key> keys() const {
PIVector<Key> 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 <typename Key1, typename T1> friend PIByteArray & operator >>(PIByteArray & s, PIDeque<typename PIHash<Key1, T1>::HashEntry> & v);
template <typename Key1, typename T1> friend PIByteArray & operator <<(PIByteArray & s, const PIDeque<typename PIHash<Key1, T1>::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<PIVector<HashEntry> > 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<PIVector<HashEntry> > pih_content;
}; };
template<typename T> template<typename Key, typename Type>
inline PICout operator <<(PICout s, const PIHash<T> & v) { inline PICout operator <<(PICout s, const PIHash<Key, Type> & v) {
s.space(); s.space();
s.setControl(0, true); s.setControl(0, true);
s << "{"; s << "{";
for (size_t i = 0; i < v.size(); ++i) { bool first = true;
s << v[i]; for (typename PIHash<Key, Type>::const_iterator i = v.begin(); i != v.end(); ++i) {
if (i < v.size() - 1) if (!first)
s << ", "; s << ", ";
first = false;
s << i.key() << ": " << i.value();
} }
s << "}"; s << "}";
s.restoreControl(); s.restoreControl();
@@ -91,20 +319,22 @@ inline PICout operator <<(PICout s, const PIHash<T> & v) {
int main() { int main() {
PIHash<PIString> v; PIHash<PIString, PIString> h;
v << "x"; h["1"] = "x";
v << "bbb"; h["2"] = "bbb";
v << "bbc"; h["3"] = "bbc";
v << "aaa"; h["4"] = "aaa";
v << "123"; h["5"] = "123";
v << "321"; h["6"] = "321";
v << "aaa" << "bbb" << "ccc"; h["7"] = "aaa";
piCout << v.size() << v.capacity(); piCout << h.size() << h.capacity();
//h.reserve(64);
piCout << h.keys() << h.values();
//piCout << (1 << 2); //piCout << (1 << 2);
PIHash<PIString> v2; /*PIHash<PIString> v2;
for (int i=0; i<1000; ++i) { for (int i=0; i<1000; ++i) {
v2 << PIString::fromNumber(randomi()); v2 << PIString::fromNumber(randomi());
} }*/
piCout << v2.size() << v2.capacity(); piCout << h;
return 0; return 0;
} }

View File

@@ -500,6 +500,22 @@ inline uint piHashData(const uchar * data, uint len, uint seed = 0) {
} }
template<typename T> 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<float> #define piRoundf piRound<float>
#define piRoundd piRound<double> #define piRoundd piRound<double>
#define piFloorf piFloor<float> #define piFloorf piFloor<float>

View File

@@ -316,14 +316,6 @@ __PIBYTEARRAY_SIMPLE_TYPE__(ldouble)
__PIBYTEARRAY_SIMPLE_TYPE__(PIChar) __PIBYTEARRAY_SIMPLE_TYPE__(PIChar)
template<typename T>
inline uint piHash(const T & v) {
PIByteArray ba;
ba << v;
return ba.hash();
}
template<> inline uint piHash(const PIByteArray & ba) {return ba.hash();} template<> inline uint piHash(const PIByteArray & ba) {return ba.hash();}

View File

@@ -44,7 +44,6 @@ PIIntrospectionContainers::_Type::_Type() {
PIIntrospectionContainers::PIIntrospectionContainers() { PIIntrospectionContainers::PIIntrospectionContainers() {
//printf("PIIntrospectionContainers %p\n", this); //printf("PIIntrospectionContainers %p\n", this);
crc = standardCRC_32();
} }
@@ -106,7 +105,7 @@ uint PIIntrospectionContainers::typeID(const char * tn) {
if (!tn) return 0u; if (!tn) return 0u;
size_t l = strlen(tn); size_t l = strlen(tn);
if (l == 0) return 0u; if (l == 0) return 0u;
return crc.calculate(tn, int(l)); return piHashData((const uchar*)tn, int(l));
} }

View File

@@ -61,7 +61,6 @@ public:
std::map<uint, _Type> data; std::map<uint, _Type> data;
std::map<uint, std::string> typenames; std::map<uint, std::string> typenames;
mutable PIMutex mutex; mutable PIMutex mutex;
CRC_32 crc;
}; };
PIByteArray & operator <<(PIByteArray & s, const PIIntrospectionContainers::TypeInfo & v); PIByteArray & operator <<(PIByteArray & s, const PIIntrospectionContainers::TypeInfo & v);