summaryrefslogtreecommitdiff
path: root/external/vpc/vstdlib/concommandhash.h
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /external/vpc/vstdlib/concommandhash.h
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'external/vpc/vstdlib/concommandhash.h')
-rw-r--r--external/vpc/vstdlib/concommandhash.h212
1 files changed, 212 insertions, 0 deletions
diff --git a/external/vpc/vstdlib/concommandhash.h b/external/vpc/vstdlib/concommandhash.h
new file mode 100644
index 0000000..40c0074
--- /dev/null
+++ b/external/vpc/vstdlib/concommandhash.h
@@ -0,0 +1,212 @@
+//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
+//
+// Purpose: Special case hash table for console commands
+//
+// $NoKeywords: $
+//
+//===========================================================================//
+
+#if !defined( CONCOMMANDHASH_H )
+#define CONCOMMANDHASH_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "utllinkedlist.h"
+#include "generichash.h"
+
+// This is a hash table class very similar to the CUtlHashFast, but
+// modified specifically so that we can look up ConCommandBases
+// by string names without having to actually store those strings in
+// the dictionary, and also iterate over all of them.
+// It uses separate chaining: each key hashes to a bucket, each
+// bucket is a linked list of hashed commands. We store the hash of
+// the command's string name as well as its pointer, so we can do
+// the linked list march part of the Find() operation more quickly.
+class CConCommandHash
+{
+public:
+ typedef int CCommandHashHandle_t;
+ typedef unsigned int HashKey_t;
+
+ // Constructor/Deconstructor.
+ CConCommandHash();
+ ~CConCommandHash();
+
+ // Memory.
+ void Purge( bool bReinitialize );
+
+ // Invalid handle.
+ static CCommandHashHandle_t InvalidHandle( void ) { return ( CCommandHashHandle_t )~0; }
+ inline bool IsValidHandle( CCommandHashHandle_t hHash ) const;
+
+ /// Initialize.
+ void Init( void ); // bucket count is hardcoded in enum below.
+
+ /// Get hash value for a concommand
+ static inline HashKey_t Hash( const ConCommandBase *cmd );
+
+ // Size not available; count is meaningless for multilists.
+ // int Count( void ) const;
+
+ // Insertion.
+ CCommandHashHandle_t Insert( ConCommandBase *cmd );
+ CCommandHashHandle_t FastInsert( ConCommandBase *cmd );
+
+ // Removal.
+ void Remove( CCommandHashHandle_t hHash );
+ void RemoveAll( void );
+
+ // Retrieval.
+ inline CCommandHashHandle_t Find( const char *name ) const;
+ CCommandHashHandle_t Find( const ConCommandBase *cmd ) const;
+ // A convenience version of Find that skips the handle part
+ // and returns a pointer to a concommand, or NULL if none was found.
+ inline ConCommandBase * FindPtr( const char *name ) const;
+
+ inline ConCommandBase * &operator[]( CCommandHashHandle_t hHash );
+ inline ConCommandBase *const &operator[]( CCommandHashHandle_t hHash ) const;
+
+#ifdef _DEBUG
+ // Dump a report to MSG
+ void Report( void );
+#endif
+
+ // Iteration
+ struct CCommandHashIterator_t
+ {
+ int bucket;
+ CCommandHashHandle_t handle;
+
+ CCommandHashIterator_t(int _bucket, const CCommandHashHandle_t &_handle)
+ : bucket(_bucket), handle(_handle) {};
+ // inline operator UtlHashFastHandle_t() const { return handle; };
+ };
+ inline CCommandHashIterator_t First() const;
+ inline CCommandHashIterator_t Next( const CCommandHashIterator_t &hHash ) const;
+ inline bool IsValidIterator( const CCommandHashIterator_t &iter ) const;
+ inline ConCommandBase * &operator[]( const CCommandHashIterator_t &iter ) { return (*this)[iter.handle]; }
+ inline ConCommandBase * const &operator[]( const CCommandHashIterator_t &iter ) const { return (*this)[iter.handle]; }
+private:
+ // a find func where we've already computed the hash for the string.
+ // (hidden private in case we decide to invent a custom string hash func
+ // for this class)
+ CCommandHashHandle_t Find( const char *name, HashKey_t hash) const;
+
+protected:
+ enum
+ {
+ kNUM_BUCKETS = 256,
+ kBUCKETMASK = kNUM_BUCKETS - 1,
+ };
+
+ struct HashEntry_t
+ {
+ HashKey_t m_uiKey;
+ ConCommandBase *m_Data;
+
+ HashEntry_t(unsigned int _hash, ConCommandBase * _cmd)
+ : m_uiKey(_hash), m_Data(_cmd) {};
+
+ HashEntry_t(){};
+ };
+
+ typedef CUtlFixedLinkedList<HashEntry_t> datapool_t;
+
+ CUtlVector<CCommandHashHandle_t> m_aBuckets;
+ datapool_t m_aDataPool;
+};
+
+inline bool CConCommandHash::IsValidHandle( CCommandHashHandle_t hHash ) const
+{
+ return m_aDataPool.IsValidIndex(hHash);
+}
+
+
+inline CConCommandHash::CCommandHashHandle_t CConCommandHash::Find( const char *name ) const
+{
+ return Find( name, HashStringCaseless(name) );
+}
+
+inline ConCommandBase * &CConCommandHash::operator[]( CCommandHashHandle_t hHash )
+{
+ return ( m_aDataPool[hHash].m_Data );
+}
+
+inline ConCommandBase *const &CConCommandHash::operator[]( CCommandHashHandle_t hHash ) const
+{
+ return ( m_aDataPool[hHash].m_Data );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: For iterating over the whole hash, return the index of the first element
+//-----------------------------------------------------------------------------
+CConCommandHash::CCommandHashIterator_t CConCommandHash::First() const
+{
+ // walk through the buckets to find the first one that has some data
+ int bucketCount = m_aBuckets.Count();
+ const CCommandHashHandle_t invalidIndex = m_aDataPool.InvalidIndex();
+ for ( int bucket = 0 ; bucket < bucketCount ; ++bucket )
+ {
+ CCommandHashHandle_t iElement = m_aBuckets[bucket]; // get the head of the bucket
+ if ( iElement != invalidIndex )
+ return CCommandHashIterator_t( bucket, iElement );
+ }
+
+ // if we are down here, the list is empty
+ return CCommandHashIterator_t( -1, invalidIndex );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: For iterating over the whole hash, return the next element after
+// the param one. Or an invalid iterator.
+//-----------------------------------------------------------------------------
+CConCommandHash::CCommandHashIterator_t
+CConCommandHash::Next( const CConCommandHash::CCommandHashIterator_t &iter ) const
+{
+ // look for the next entry in the current bucket
+ CCommandHashHandle_t next = m_aDataPool.Next(iter.handle);
+ const CCommandHashHandle_t invalidIndex = m_aDataPool.InvalidIndex();
+ if ( next != invalidIndex )
+ {
+ // this bucket still has more elements in it
+ return CCommandHashIterator_t(iter.bucket, next);
+ }
+
+ // otherwise look for the next bucket with data
+ int bucketCount = m_aBuckets.Count();
+ for ( int bucket = iter.bucket+1 ; bucket < bucketCount ; ++bucket )
+ {
+ CCommandHashHandle_t next = m_aBuckets[bucket]; // get the head of the bucket
+ if (next != invalidIndex)
+ return CCommandHashIterator_t( bucket, next );
+ }
+
+ // if we're here, there's no more data to be had
+ return CCommandHashIterator_t(-1, invalidIndex);
+}
+
+bool CConCommandHash::IsValidIterator( const CCommandHashIterator_t &iter ) const
+{
+ return ( (iter.bucket >= 0) && (m_aDataPool.IsValidIndex(iter.handle)) );
+}
+
+inline CConCommandHash::HashKey_t CConCommandHash::Hash( const ConCommandBase *cmd )
+{
+ return HashStringCaseless( cmd->GetName() );
+}
+
+inline ConCommandBase * CConCommandHash::FindPtr( const char *name ) const
+{
+ CCommandHashHandle_t handle = Find(name);
+ if (handle == InvalidHandle())
+ {
+ return NULL;
+ }
+ else
+ {
+ return (*this)[handle];
+ }
+}
+
+#endif