summaryrefslogtreecommitdiff
path: root/gcsdk/bufferpool.cpp
blob: f1c2f8218b1583dcdc8617bcd90007d4d83916e6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//========= Copyright �, Valve LLC, All rights reserved. ======================
//
// Purpose: Defines a buffer pool used to group small allocations
//
//=============================================================================


#include "stdafx.h"
#include "bufferpool.h"

using namespace GCSDK;

CUtlVector<CBufferPool *> CBufferPool::sm_vecBufferPools;


//----------------------------------------------------------------------------
// Purpose: Constructor
//----------------------------------------------------------------------------
CBufferPool::CBufferPool( const char *pchName, const GCConVar &cvMaxSizeMB, const GCConVar &cvInitBufferSize, int nFlags )
	:	m_nBuffersInUse( 0 )
	,	m_nBuffersTotal( 0 )
	,	m_nHighWatermark( 0 )
	,	m_cubFree( 0 )
	,	m_sName( pchName )
	,	m_cvMaxSizeMB( cvMaxSizeMB )
	,	m_cvInitBufferSize( cvInitBufferSize )
	,	m_nFlags( nFlags )
{
	sm_vecBufferPools.AddToTail( this );
}


//----------------------------------------------------------------------------
// Purpose: Destructor
//----------------------------------------------------------------------------
CBufferPool::~CBufferPool()
{
	m_vecFreeBuffers.PurgeAndDeleteElements();
	sm_vecBufferPools.FindAndRemove( this );
}


//----------------------------------------------------------------------------
// Purpose: Gives a bind param buffer to a query
//----------------------------------------------------------------------------
CUtlBuffer *CBufferPool::GetBuffer()
{
	m_nBuffersInUse++;

	if ( m_vecFreeBuffers.Count() > 0 )
	{
		CUtlBuffer *pBuffer = m_vecFreeBuffers.Tail();
		m_vecFreeBuffers.Remove( m_vecFreeBuffers.Count() - 1 );
		m_cubFree -= pBuffer->Size();

		return pBuffer;
	}
	else
	{
		m_nBuffersTotal++;
		m_nHighWatermark = max( m_nBuffersTotal, m_nHighWatermark );
		return new CUtlBuffer( 0, m_cvInitBufferSize.GetInt(), m_nFlags );
	}
}


//----------------------------------------------------------------------------
// Purpose: Returns a bind param buffer when a query is done with it
//----------------------------------------------------------------------------
void CBufferPool::ReturnBuffer( CUtlBuffer *pBuffer )
{
	m_nBuffersInUse--;

	if ( ( int64 )( m_cubFree + pBuffer->Size() ) <= ( m_cvMaxSizeMB.GetInt() * k_nMegabyte ) )
	{
		pBuffer->Clear();
		m_cubFree += pBuffer->Size();
		m_vecFreeBuffers.AddToTail( pBuffer );
	}
	else
	{
		m_nBuffersTotal--;
		delete pBuffer;
	}
}


//----------------------------------------------------------------------------
// Purpose: Print statistics to the console
//----------------------------------------------------------------------------
void CBufferPool::DumpPools()
{
	EmitInfo( SPEW_CONSOLE, SPEW_ALWAYS, LOG_ALWAYS, "Reusable Buffer Pools:\n" );
	EmitInfo( SPEW_CONSOLE, SPEW_ALWAYS, LOG_ALWAYS, 
		"  Pool                                Buffers         Free  Max Buffers  Total Mem (est)         Free Mem\n" );
	EmitInfo( SPEW_CONSOLE, SPEW_ALWAYS, LOG_ALWAYS, 
		"  ------------------------------ ------------ ------------ ------------ ---------------- ----------------\n" );

	FOR_EACH_VEC( sm_vecBufferPools, i )
	{
		CBufferPool *pPool = sm_vecBufferPools[i];

		int nTotalEst = 0;
		if ( pPool->m_vecFreeBuffers.Count() > 0 )
		{
			nTotalEst = pPool->m_cubFree / pPool->m_vecFreeBuffers.Count() * pPool->m_nBuffersTotal;
		}

		EmitInfo( SPEW_CONSOLE, SPEW_ALWAYS, LOG_ALWAYS, "  %-30s %12d %12d %12d %16s %16s\n",
			pPool->m_sName.Get(),
			pPool->m_nBuffersTotal,
			pPool->m_vecFreeBuffers.Count(),
			pPool->m_nHighWatermark,
			Q_pretifymem( nTotalEst, 0, true ),
			Q_pretifymem( pPool->m_cubFree, 0, true )
		);
	}

	EmitInfo( SPEW_CONSOLE, SPEW_ALWAYS, LOG_ALWAYS, "\n" );
}