//--------------------------------------------------------------------------- // Greenplum Database // Copyright (C) 2011 EMC Corp. // // @filename: // CSyncHashtableAccessorBase.h // // @doc: // Base hashtable accessor class; provides primitives to operate // on a target bucket in the hashtable. // //--------------------------------------------------------------------------- #ifndef GPOS_CSyncHashtableAccessorBase_H_ #define GPOS_CSyncHashtableAccessorBase_H_ #include "gpos/base.h" #include "gpos/common/CSyncHashtable.h" #include "gpos/common/CSyncHashtableIter.h" namespace gpos { //--------------------------------------------------------------------------- // @class: // CSyncHashtableAccessorBase // // @doc: // Accessor class to encapsulate locking of a hashtable bucket; // has to know all template parameters of the hashtable class in order // to link to the target hashtable; see file doc for more details on the // rationale behind this class // //--------------------------------------------------------------------------- template class CSyncHashtableAccessorBase : public CStackObject { private: // shorthand for buckets using SBucket = typename gpos::CSyncHashtable::SBucket; // target hashtable CSyncHashtable &m_ht; // bucket to operate on SBucket &m_bucket; protected: // ctor - protected to restrict instantiation to children CSyncHashtableAccessorBase(CSyncHashtable &ht, ULONG bucket_idx) : m_ht(ht), m_bucket(m_ht.GetBucket(bucket_idx)) { } // dtor virtual ~CSyncHashtableAccessorBase() = default; // accessor to hashtable CSyncHashtable & GetHashTable() const { return m_ht; } // accessor to maintained bucket SBucket & GetBucket() const { return m_bucket; } // returns the first element in the hash chain T * First() const { return m_bucket.m_chain.First(); } // finds the element next to the given one T * Next(T *value) const { GPOS_ASSERT(nullptr != value); // make sure element is in this hash chain GPOS_ASSERT(GPOS_OK == m_bucket.m_chain.Find(value)); return m_bucket.m_chain.Next(value); } // inserts element at the head of hash chain void Prepend(T *value) { GPOS_ASSERT(nullptr != value); m_bucket.m_chain.Prepend(value); // increase number of entries m_ht.m_size++; } // adds first element before second element void Prepend(T *value, T *ptNext) { GPOS_ASSERT(nullptr != value); // make sure element is in this hash chain GPOS_ASSERT(GPOS_OK == m_bucket.m_chain.Find(ptNext)); m_bucket.m_chain.Prepend(value, ptNext); // increase number of entries m_ht.m_size++; } // adds first element after second element void Append(T *value, T *ptPrev) { GPOS_ASSERT(nullptr != value); // make sure element is in this hash chain GPOS_ASSERT(GPOS_OK == m_bucket.m_chain.Find(ptPrev)); m_bucket.m_chain.Append(value, ptPrev); // increase number of entries m_ht.m_size++; } public: CSyncHashtableAccessorBase(const CSyncHashtableAccessorBase &) = delete; // unlinks element void Remove(T *value) { // not NULL and is-list-member checks are done in CList m_bucket.m_chain.Remove(value); // decrease number of entries m_ht.m_size--; } }; // class CSyncHashtableAccessorBase } // namespace gpos #endif // GPOS_CSyncHashtableAccessorBase_H_ // EOF