#pragma once #ifndef UTILITY_OBJKEY_GENERATOR_H #define UTILITY_OBJKEY_GENERATOR_H #include #include #pragma pack(push) #pragma pack() namespace util { ; //================================================================================================== // // - Objectµé¿¡ Key¸¦ ¹ß±ÞÇϰí ȸ¼öÇÏ´Â ¸Å´ÏÀú // // - 040906 : (ver1.0) Created // - 080519 : (ver1.1) DataStructure Changed & Bug Fix (by MjKim) // - 080520 : (ver1.2) Server Support by replacing datastructure (by Waverix) // - ver1.1À» Server¿¡¼­ »ç¿ëÇϴµ¥´Â À§ÇèºÎ´ãÀÌ ³ô¾ÆÁö´Â °ü°è·Î ÀڷᱸÁ¶ º¯°æ (1.1ÀÇ ¸ñÀûµµ ¹Ý¿µ) // // - 0x0100 - general // - 0x0110 // - 0x0120 // - 0x0130 - (ver1.3) change to an enhanced 'ReserveKey' to support client local handling // #define __OBJKEYGEN_VERSION_CTRL 0x0130 // #if __OBJKEYGEN_VERSION_CTRL == 0x0130 //================================================================================================== // version 0.1.3.0 namespace internal { ; class ObjectKeyGeneratorBase { public: typedef ulong key_type; //static const key_type kMaxKeyBandwidth = (USHRT_MAX << 2); // (ULONG_MAX >> 2); static const key_type kMaxKeyBandwidth = (ULONG_MAX >> 2); // (ULONG_MAX >> 2); static const key_type kEmptyKey = 0; // ObjectKeyGeneratorBase(); ObjectKeyGeneratorBase(key_type start_key, key_type end_key); ~ObjectKeyGeneratorBase(); // bool Create(key_type start_key, key_type end_key); key_type GetKey(); bool RestoreKey(key_type key); bool IsExistKey(key_type key) const; bool ReserveKey(key_type key); bool IsEmpty() const; size_t GetSize() const; private: static const BOOLEAN kColorOfIssued = true; static const BOOLEAN kColorOfFree = !kColorOfIssued; #pragma pack(push, 1) struct AlignNode { BOOLEAN color_; }; #pragma pack(pop) // typedef STLX_DEQUE KeySet; // Free Key Set // // data fields... bool initialized_; key_type lower_bound_; key_type upper_bound_; int number_of_free_; AlignNode* total_array_; KeySet free_key_set_; }; //-------------------------------------------------------------------------------------------------- // implements inline ObjectKeyGeneratorBase::ObjectKeyGeneratorBase() : initialized_(false), lower_bound_(0), upper_bound_(0), number_of_free_(0), total_array_(NULL) { } inline ObjectKeyGeneratorBase::ObjectKeyGeneratorBase(key_type start_key, key_type end_key) { Create(start_key, end_key); } inline bool ObjectKeyGeneratorBase::IsExistKey(key_type key) const { if (lower_bound_ <= key && key < upper_bound_) { const key_type offset = key - lower_bound_; const AlignNode* align = &total_array_[offset]; return (kColorOfFree == align->color_); } return false; } inline bool ObjectKeyGeneratorBase::IsEmpty() const { return number_of_free_ <= 0; } inline size_t ObjectKeyGeneratorBase::GetSize() const { return number_of_free_; } }; //end of nested namespace 'internal' //================================================================================================== // template class CObjKeyGenerator : public internal::ObjectKeyGeneratorBase { public: typedef _KEYTYPE key_type; // acceptable types = { uint8_t, uint16_t, uint32_t, ulong(DWORD) } BOOST_STATIC_ASSERT(\ boost::is_integral::value && sizeof(key_type) <= sizeof(typename internal::ObjectKeyGeneratorBase::key_type) && static_cast(-1) > 0); // CObjKeyGenerator(); CObjKeyGenerator(key_type start_key, key_type end_key); ~CObjKeyGenerator(); // bool Create(key_type start_key, key_type end_key); key_type GetKey(); bool RestoreKey(key_type key); bool IsExistKey(key_type key) const; bool ReserveKey(key_type key); bool IsEmpty() const; size_t GetSize() const; }; //-------------------------------------------------------------------------------------------------- // implements template inline CObjKeyGenerator<_KEYTYPE>::CObjKeyGenerator() { } template inline CObjKeyGenerator<_KEYTYPE>::CObjKeyGenerator(key_type start_key, key_type end_key) { ObjectKeyGeneratorBase::Create(start_key, end_key); } template inline bool CObjKeyGenerator<_KEYTYPE>::Create(key_type start_key, key_type end_key) { return ObjectKeyGeneratorBase::Create(start_key, end_key); } template inline CObjKeyGenerator<_KEYTYPE>::~CObjKeyGenerator() { } template inline typename CObjKeyGenerator<_KEYTYPE>::key_type CObjKeyGenerator<_KEYTYPE>::GetKey() { return static_cast(ObjectKeyGeneratorBase::GetKey()); } template inline bool CObjKeyGenerator<_KEYTYPE>::RestoreKey(key_type key) { return ObjectKeyGeneratorBase::RestoreKey(key); } template inline bool CObjKeyGenerator<_KEYTYPE>::IsExistKey(key_type key) const { return ObjectKeyGeneratorBase::IsExistKey(key); } template inline bool CObjKeyGenerator<_KEYTYPE>::ReserveKey(key_type key) { return ObjectKeyGeneratorBase::ReserveKey(key); } template inline bool CObjKeyGenerator<_KEYTYPE>::IsEmpty() const { return ObjectKeyGeneratorBase::IsEmpty(); } template inline size_t CObjKeyGenerator<_KEYTYPE>::GetSize() const { return ObjectKeyGeneratorBase::GetSize(); } // //================================================================================================== #elif __OBJKEYGEN_VERSION_CTRL == 0x0120 //================================================================================================== // version 0.1.2.0 template class CObjKeyGenerator { public: CObjKeyGenerator( VOID ); CObjKeyGenerator( const _KEYTYPE startKey, const _KEYTYPE endKey ); ~CObjKeyGenerator( VOID ); public: //¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡ // public: VOID Create( const _KEYTYPE startKey, const _KEYTYPE endKey ); _KEYTYPE GetKey( VOID ); VOID RestoreKey( const _KEYTYPE key ); BOOL IsExistKey( const _KEYTYPE key ); BOOL ReserveKey( const _KEYTYPE key ); BOOL IsEmpty( VOID ); SIZE_T GetSize( VOID ); private: static const BOOLEAN COLOR_ISSUE = TRUE; static const BOOLEAN COLOR_FREE = FALSE; struct sALIGN { _KEYTYPE KEY; BOOLEAN COLOR; }; typedef STLX_DEQUE<_KEYTYPE> KeySet; // Free Key Set typedef STLX_VECTOR TotalSet; // Set for total managed key private: _KEYTYPE m_Lowerbound; _KEYTYPE m_Upperbound; KeySet m_keySet; TotalSet m_TotalKey; }; template CObjKeyGenerator<_KEYTYPE>::CObjKeyGenerator( VOID ) { m_Lowerbound = m_Upperbound = 0; } template CObjKeyGenerator<_KEYTYPE>::CObjKeyGenerator( const _KEYTYPE startKey, const _KEYTYPE endKey ) { Create( startKey, endKey ); } template VOID CObjKeyGenerator<_KEYTYPE>::Create( const _KEYTYPE startKey, const _KEYTYPE endKey ) { ASSERT( (startKey < endKey) && m_keySet.empty() ); m_Lowerbound = startKey; m_Upperbound = endKey + 1 ; // [lb, endKey] -> [lb, up) const _KEYTYPE range = m_Upperbound-m_Lowerbound; // deque´Â reserve°¡ ¾ø¾î¿ë m_TotalKey.reserve( range ); sALIGN alignS = { 0, COLOR_FREE }; for( _KEYTYPE key=m_Lowerbound ; key CObjKeyGenerator<_KEYTYPE>::~CObjKeyGenerator( VOID ) { m_Lowerbound = m_Upperbound = 0; } template _KEYTYPE CObjKeyGenerator<_KEYTYPE>::GetKey( VOID ) { if( m_keySet.empty() ) { ASSERT( !"ÇÒ´çÇÒ ¼ö Àִ Ű°¡ ¾ø½À´Ï´Ù." ); return (_KEYTYPE)0; } KeySet::iterator it = m_keySet.begin(); const _KEYTYPE issue_key = *it; const _KEYTYPE index = issue_key-m_Lowerbound; sALIGN& rAlign = m_TotalKey[index]; rAlign.COLOR = COLOR_ISSUE; m_keySet.pop_front(); return issue_key; } template VOID CObjKeyGenerator<_KEYTYPE>::RestoreKey( const _KEYTYPE key ) { if( m_Lowerbound<=key && key BOOL CObjKeyGenerator<_KEYTYPE>::IsExistKey( const _KEYTYPE key ) { if( m_Lowerbound<=key && key BOOL CObjKeyGenerator<_KEYTYPE>::ReserveKey( const _KEYTYPE key ) { if( m_Lowerbound<=key && key BOOL CObjKeyGenerator<_KEYTYPE>::IsEmpty( VOID ) { return ( m_keySet.empty() ); } template SIZE_T CObjKeyGenerator<_KEYTYPE>::GetSize( VOID ) { return m_keySet.size(); } //================================================================================================== #else //__OBJKEYGEN_VERSION_CTRL < 0x0120 ; // #endif }; // End of Namespace Util #pragma pack(pop) #endif //UTILITY_OBJKEY_GENERATOR_H