ultimatepp/uppsrc/Core/Index.h
cxl e97c59d886 Core: Container::Pop now with pick allows Poping containers
git-svn-id: svn://ultimatepp.org/upp/trunk@10627 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2017-01-03 09:37:00 +00:00

210 lines
7.4 KiB
C++

#define FOLDHASH
enum { UNSIGNED_HIBIT = 0x80000000 };
class HashBase : Moveable<HashBase> {
struct Link : Moveable<Link> {
int next;
int prev;
};
Vector<unsigned> hash;
Vector<Link> link;
int *map;
int mask;
int unlinked;
void LinkBefore(int i, Link& l, int bi);
void LinkTo(int i, Link& l, int& m);
void Unlink(int i, Link& l, int& mi);
void Unlink(int i, Link& l);
int& Maph(unsigned _hash) const;
int& Mapi(int i) const;
void FinishIndex();
void Zero();
void Free();
public:
void ClearIndex();
void Reindex(int n);
void Reindex();
void Add(unsigned hash);
void Set(int i, unsigned hash);
void SetUn(int i, unsigned hash);
unsigned operator [] (int i) const { return hash[i]; }
int Find(unsigned hash) const;
int GetNext(int i) const { return link[i].next; }
int FindNext(int i, int first) const;
int FindNext(int i) const;
int FindLast(unsigned hash) const;
int FindPrev(int i) const;
int Put(unsigned hash);
bool IsUnlinked(int i) const { return hash[i] & UNSIGNED_HIBIT; }
void Unlink(int i);
Vector<int> GetUnlinked() const;
bool HasUnlinked() const { return unlinked >= 0; }
void Remove(int i);
void Remove(int i, int count);
void Remove(const int *sorted_list, int count);
void Insert(int i, unsigned hash);
int GetCount() const { return hash.GetCount(); }
void Trim(int count);
void Drop(int n);
void Clear() { hash.Clear(); ClearIndex(); }
void Reserve(int n);
void Shrink();
#ifdef UPP
void Serialize(Stream& s);
#endif
HashBase();
~HashBase();
HashBase(HashBase&& b);
void operator=(HashBase&& b);
HashBase(const HashBase& b, int);
void operator<<=(const HashBase& b);
const unsigned *Begin() const { return hash.Begin(); }
const unsigned *End() const { return hash.End(); }
void Swap(HashBase& b);
};
template <class T>
class Index : MoveableAndDeepCopyOption<Index<T>> {
protected:
Vector<T> key;
HashBase hash;
int Find0(const T& x, int i) const {
while(i >= 0 && !(x == key[i])) i = hash.FindNext(i);
return i;
}
int FindB(const T& x, int i) const {
while(i >= 0 && !(x == key[i])) i = hash.FindPrev(i);
return i;
}
void Hash();
public:
unsigned hashfn(const T& x) const { return GetHashValue(x); }
T& Add(const T& x, unsigned _hash);
T& Add(const T& x);
Index& operator<<(const T& x) { Add(x); return *this; }
int FindAdd(const T& key, unsigned _hash);
int FindAdd(const T& key);
int Put(const T& x, unsigned _hash);
int Put(const T& x);
int FindPut(const T& key, unsigned _hash);
int FindPut(const T& key);
int Find(const T& x, unsigned _hash) const;
int Find(const T& x) const;
int FindNext(int i) const;
int FindLast(const T& x, unsigned _hash) const;
int FindLast(const T& x) const;
int FindPrev(int i) const;
T& Set(int i, const T& x, unsigned _hash);
T& Set(int i, const T& x);
const T& operator[](int i) const { return key[i]; }
int GetCount() const { return key.GetCount(); }
bool IsEmpty() const { return key.IsEmpty(); }
unsigned GetHash(int i) const { return hash[i]; }
void Clear() { hash.Clear(); key.Clear(); }
void Unlink(int i) { hash.Unlink(i); }
int UnlinkKey(const T& k, unsigned h);
int UnlinkKey(const T& k);
bool IsUnlinked(int i) const { return hash.IsUnlinked(i); }
Vector<int> GetUnlinked() const { return hash.GetUnlinked(); }
void Sweep();
bool HasUnlinked() const { return hash.HasUnlinked(); }
T& Insert(int i, const T& k, unsigned h);
T& Insert(int i, const T& k);
void Remove(int i);
void Remove(int i, int count);
void Remove(const int *sorted_list, int count);
void Remove(const Vector<int>& sorted_list);
int RemoveKey(const T& k, unsigned h);
int RemoveKey(const T& k);
void Trim(int n) { key.SetCount(n); hash.Trim(n); }
void Drop(int n = 1) { key.Drop(n); hash.Drop(n); }
const T& Top() const { return key.Top(); }
T Pop() { T x = pick(Top()); Drop(); return x; }
void Reserve(int n) { key.Reserve(n); hash.Reserve(n); }
void Shrink() { key.Shrink(); hash.Shrink(); }
int GetAlloc() const { return key.GetAlloc(); }
void Serialize(Stream& s);
void Xmlize(XmlIO& xio, const char *itemtag = "key");
void Jsonize(JsonIO& jio);
String ToString() const;
template <class B> bool operator==(const B& b) const { return IsEqualRange(*this, b); }
template <class B> bool operator!=(const B& b) const { return !operator==(b); }
template <class B> int Compare(const B& b) const { return CompareRanges(*this, b); }
template <class B> bool operator<=(const B& x) const { return Compare(x) <= 0; }
template <class B> bool operator>=(const B& x) const { return Compare(x) >= 0; }
template <class B> bool operator<(const B& x) const { return Compare(x) < 0; }
template <class B> bool operator>(const B& x) const { return Compare(x) > 0; }
Vector<T> PickKeys() { Vector<T> r = pick(key); Clear(); return r; }
const Vector<T>& GetKeys() const { return key; }
Index() {}
Index(Index&& s) : key(pick(s.key)), hash(pick(s.hash)) {}
Index(const Index& s, int) : key(s.key, 0), hash(s.hash, 0) {}
explicit Index(Vector<T>&& s) : key(pick(s)) { Hash(); }
Index(const Vector<T>& s, int) : key(s, 0) { Hash(); }
Index& operator=(Vector<T>&& x) { key = pick(x); Hash(); return *this; }
Index& operator=(Index<T>&& x) { key = pick(x.key); hash = pick(x.hash); return *this; }
Index(std::initializer_list<T> init) : key(init) { Hash(); }
typedef ConstIteratorOf<Vector<T>> ConstIterator;
// Standard container interface
ConstIterator begin() const { return key.Begin(); }
ConstIterator end() const { return key.End(); }
friend void Swap(Index& a, Index& b) { UPP::Swap(a.hash, b.hash);
UPP::Swap(a.key, b.key); }
#ifdef DEPRECATED
Index& operator<<=(const Vector<T>& s) { *this = clone(s); return *this; }
typedef T ValueType;
typedef Vector<T> ValueContainer;
ConstIterator GetIter(int pos) const { return key.GetIter(pos); }
void ClearIndex() { hash.ClearIndex(); }
void Reindex(int n) { hash.Reindex(n); }
void Reindex() { hash.Reindex(); }
typedef T value_type;
typedef ConstIterator const_iterator;
typedef const T& const_reference;
typedef int size_type;
typedef int difference_type;
const_iterator Begin() const { return begin(); }
const_iterator End() const { return end(); }
void clear() { Clear(); }
size_type size() { return GetCount(); }
bool empty() const { return IsEmpty(); }
#endif
};