111 lines
2.9 KiB
C++
111 lines
2.9 KiB
C++
#include "pip.h"
|
|
|
|
|
|
template <typename T>
|
|
class PIHash {
|
|
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();}
|
|
|
|
inline PIHash<T> & 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<content.size_s(); ++i) piCout << i << content[i].first << content[i].second;
|
|
return *this;
|
|
}
|
|
inline PIHash<T> & append(const T & v) {return push_back(v);}
|
|
// inline PIVector<T> & append(const PIVector<T> & 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<T> & operator <<(const T & v) {return push_back(v);}
|
|
// inline PIVector<T> & operator <<(const PIVector<T> & other) {return append(other);}
|
|
private:
|
|
typedef PIPair<uint, T> HashPair;
|
|
void add_hash(uint nh) {
|
|
piCout << "add" << nh;
|
|
//for (int i=0; i<content.size_s(); ++i) piCout << i << content[i].first << content[i].second;
|
|
if (nh == 0) {
|
|
piCout << "invalid hash";
|
|
return;
|
|
}
|
|
if (shift == 0) {
|
|
shift++;
|
|
content.resize(1 << shift, HashPair(0, T()));
|
|
}
|
|
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();
|
|
}
|
|
//for (int i=0; i<content.size_s(); ++i) piCout << i << content[i].first << content[i].second;
|
|
}
|
|
void rehash() {
|
|
piCout << "rehash";
|
|
PIVector<PIPair<uint, T> > tmpc(content.size(), HashPair(0, T()));
|
|
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);
|
|
}
|
|
|
|
PIVector<PIPair<uint, T> > content;
|
|
uint shift;
|
|
size_t r_size;
|
|
};
|
|
|
|
|
|
template<typename T>
|
|
inline PICout operator <<(PICout s, const PIHash<T> & 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)
|
|
s << ", ";
|
|
}
|
|
s << "}";
|
|
s.restoreControl();
|
|
return s;
|
|
}
|
|
|
|
|
|
int main() {
|
|
PIHash<PIString> v;
|
|
v << "x";
|
|
v << "bbb";
|
|
v << "bbc";
|
|
v << "aaa";
|
|
v << "123";
|
|
v << "321";
|
|
v << "aaa" << "bbb" << "ccc";
|
|
piCout << v.size() << v.capacity();
|
|
//piCout << (1 << 2);
|
|
PIHash<PIString> v2;
|
|
for (int i=0; i<1000; ++i) {
|
|
v2 << PIString::fromNumber(randomi());
|
|
}
|
|
piCout << v2.size() << v2.capacity();
|
|
return 0;
|
|
}
|