Skip to content

Commit

Permalink
Update CKeyValues3Array container
Browse files Browse the repository at this point in the history
Co-authored-by: Nyano <[email protected]>
  • Loading branch information
Wend4r and Nyano1337 committed Dec 26, 2024
1 parent 20a9408 commit 29a6d88
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 35 deletions.
33 changes: 21 additions & 12 deletions public/tier1/keyvalues3.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ enum
enum
{
KV3_TABLE_MAX_FIXED_MEMBERS = 8,
KV3_ARRAY_MAX_FIXED_MEMBERS = 6,
};

enum
Expand Down Expand Up @@ -482,31 +483,39 @@ COMPILE_TIME_ASSERT(sizeof(KeyValues3) == 16);
class CKeyValues3Array
{
public:
CKeyValues3Array( int cluster_elem = -1 );
CKeyValues3Array( int alloc_size = 0, int cluster_elem = -1 );

int GetClusterElement() const { return m_nClusterElement; }
CKeyValues3ArrayCluster* GetCluster() const;
CKeyValues3Context* GetContext() const;

KeyValues3** Base() { return m_Elements.Base(); }
KeyValues3* const * Base() const { return m_Elements.Base(); }

KeyValues3* Element( int i ) { return m_Elements[ i ]; }
const KeyValues3* Element( int i ) const { return m_Elements[ i ]; }
KeyValues3** Base();
KeyValues3* const * Base() const { return const_cast<CKeyValues3Array*>(this)->Base(); }
KeyValues3* Element( int i );
const KeyValues3* Element( int i ) const { return const_cast<CKeyValues3Array*>(this)->Element( i ); }
int Count() const { return m_nCount; }

int Count() const { return m_Elements.Count(); }
void SetCount( int count, KV3TypeEx_t type = KV3_TYPEEX_NULL, KV3SubType_t subtype = KV3_SUBTYPE_UNSPECIFIED );
KeyValues3** InsertBeforeGetPtr( int elem, int num );
void CopyFrom( const CKeyValues3Array* pSrc );
void RemoveMultiple( int elem, int num );
void Purge( bool bClearingContext );

private:
typedef CUtlLeanVectorFixedGrowable<KeyValues3*, 6, int> ElementsVec_t;

int m_nClusterElement;
ElementsVec_t m_Elements;
public:
int m_nClusterElement;
int m_nAllocatedChunks;

int m_nCount;
int8 m_nInitialSize;
bool m_bIsDynamicallySized;

union Data_t
{
KeyValues3* m_Members[KV3_ARRAY_MAX_FIXED_MEMBERS];
KeyValues3** m_pChunks;
} m_Data;
};
COMPILE_TIME_ASSERT(sizeof(CKeyValues3Array) == 64);

class CKeyValues3Table
{
Expand Down
95 changes: 72 additions & 23 deletions tier1/keyvalues3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1150,9 +1150,22 @@ KeyValues3& KeyValues3::operator=( const KeyValues3& src )
return *this;
}

CKeyValues3Array::CKeyValues3Array( int cluster_elem ) :
m_nClusterElement( cluster_elem )
CKeyValues3Array::CKeyValues3Array( int alloc_size, int cluster_elem ) :
m_nCount(0),
m_bIsDynamicallySized(false)
{
m_nClusterElement = cluster_elem;

if ( alloc_size >= 256 )
{
m_nInitialSize = -1;
m_nClusterElement = alloc_size;
}
else
{
m_nInitialSize = KV3_ARRAY_MAX_FIXED_MEMBERS;
m_nClusterElement = KV3_ARRAY_MAX_FIXED_MEMBERS;
}
}

CKeyValues3ArrayCluster* CKeyValues3Array::GetCluster() const
Expand All @@ -1173,68 +1186,102 @@ CKeyValues3Context* CKeyValues3Array::GetContext() const
return NULL;
}

KeyValues3** CKeyValues3Array::Base()
{
if ( m_bIsDynamicallySized )
return &m_Data.m_pChunks[0];

return &m_Data.m_Members[0];
}

KeyValues3* CKeyValues3Array::Element( int i )
{
Assert( 0 <= i && i < m_nCount );

return Base()[i];
}

void CKeyValues3Array::SetCount( int count, KV3TypeEx_t type, KV3SubType_t subtype )
{
int nOldSize = m_Elements.Count();
int nOldSize = m_nCount;

CKeyValues3Context* context = GetContext();

for ( int i = count; i < nOldSize; ++i )
{
KeyValues3 *pElement = m_Data.m_Members[i];

if ( context )
context->FreeKV( m_Elements[ i ] );
context->FreeKV( pElement );
else
{
m_Elements[ i ]->Free( true );
free( m_Elements[ i ] );
pElement->Free( true );
free( pElement );
}
}

m_Elements.SetCount( count );
KeyValues3 **pNew = &m_Data.m_Members[0];

if ( count > nOldSize && count > KV3_ARRAY_MAX_FIXED_MEMBERS )
{
pNew = (KeyValues3**)( m_bIsDynamicallySized ? realloc( m_Data.m_pChunks, count ) : malloc( count ) );

memmove( pNew, Base(), m_nAllocatedChunks * sizeof(KeyValues3*) );

m_Data.m_pChunks = pNew;
m_nAllocatedChunks = count;
m_bIsDynamicallySized = true;
}

m_nCount = count;

for ( int i = nOldSize; i < count; ++i )
{
if ( context )
m_Elements[ i ] = context->AllocKV( type, subtype );
pNew[i] = context->AllocKV(type, subtype);
else
m_Elements[ i ] = new KeyValues3( type, subtype );
pNew[i] = new KeyValues3(type, subtype);
}
}

KeyValues3** CKeyValues3Array::InsertBeforeGetPtr( int elem, int num )
{
KeyValues3** kv = m_Elements.InsertBeforeGetPtr( elem, num );
KeyValues3** kv = Base();

CKeyValues3Context* context = GetContext();

for ( int i = 0; i < num; ++i )
{
if ( context )
m_Elements[ elem + i ] = context->AllocKV();
kv[elem + i] = context->AllocKV();
else
m_Elements[ elem + i ] = new KeyValues3;
kv[elem + i] = new KeyValues3;
}

return kv;
}

void CKeyValues3Array::CopyFrom( const CKeyValues3Array* pSrc )
{
int nNewSize = pSrc->m_Elements.Count();
KeyValues3** kv = Base();
KeyValues3* const * pSrcKV = pSrc->Base();

int nNewSize = pSrc->Count();

SetCount( nNewSize );

for ( int i = 0; i < nNewSize; ++i )
*m_Elements[i] = *pSrc->m_Elements[i];
*kv[i] = *pSrcKV[i];
}

void CKeyValues3Array::RemoveMultiple( int elem, int num )
{
CKeyValues3Context* context = GetContext();
KeyValues3 **kv = Base();

for ( int i = 0; i < num; ++i )
for ( int i = 0; i <= num; ++i )
{
auto &Element = m_Elements[ elem + i ];
auto &Element = kv[ elem + i ];

if ( context )
context->FreeKV( Element );
Expand All @@ -1244,29 +1291,31 @@ void CKeyValues3Array::RemoveMultiple( int elem, int num )
free( Element );
}
}

m_Elements.RemoveMultiple( elem, num );
}

void CKeyValues3Array::Purge( bool bClearingContext )
{
CKeyValues3Context* context = GetContext();
KeyValues3 **kv = Base();

FOR_EACH_LEANVEC( m_Elements, iter )
for ( int i = 0; i < m_nCount; i++ )
{
if ( context )
{
if ( !bClearingContext )
context->FreeKV( m_Elements[ iter ] );
context->FreeKV( kv[ i ] );
}
else
{
m_Elements[ iter ]->Free( true );
free( m_Elements[ iter ] );
kv[ i ]->Free( true );
free( kv[ i ] );
}
}

m_Elements.Purge();
if ( m_bIsDynamicallySized )
free( m_Data.m_pChunks );

m_nCount = 0;
}

CKeyValues3Table::CKeyValues3Table( int cluster_elem ) :
Expand Down

0 comments on commit 29a6d88

Please sign in to comment.