<commit_before>

#define SGS_INTERNAL
#include <sgs_int.h>

#include "sgs_prof.h"



static void mode1hook( void* userdata, SGS_CTX, int evid )
{
	SGS_PROF = (sgs_Prof*) userdata;
	double TM = sgs_GetTime();
	if( P->hfn )
		P->hfn( P->hctx, C, evid );

	if( evid == SGS_HOOK_ENTER )
	{
		const char* fname = "<error>";
		sgs_StackFrame* sf = sgs_GetFramePtr( C, 1 );
		sgs_StackFrameInfo( C, sf, &fname, NULL, NULL );
		membuf_appbuf( &P->keytmp, C, fname, strlen( fname ) );
		membuf_appchr( &P->keytmp, C, 0 );
		membuf_appbuf( &P->timetmp, C, &TM, sizeof(TM) );
	}
	else if( evid == SGS_HOOK_EXIT && P->keytmp.size )
	{
		double prevTM;
		HTPair* pair;
		int prevzeroat = P->keytmp.size - 1;
		while( prevzeroat --> 0 )
			if( P->keytmp.ptr[ prevzeroat ] == 0 )
				break;

		prevTM = AS_DOUBLE( P->timetmp.ptr + P->timetmp.size - sizeof(double) );
		pair = ht_find( &P->timings, P->keytmp.ptr, P->keytmp.size,
			sgs_HashFunc( P->keytmp.ptr, P->keytmp.size ) );
		if( pair )
		{
			AS_DOUBLE( pair->ptr ) += TM - prevTM;
		}
		else
		{
			double* val = sgs_Alloc( double );
			*val = TM - prevTM;
			ht_set( &P->timings, C, P->keytmp.ptr, P->keytmp.size, val );
		}


		membuf_resize( &P->keytmp, C, prevzeroat ? prevzeroat + 1 : 0 );
		membuf_resize( &P->timetmp, C, P->timetmp.size - sizeof(TM) );
	}
}

static int initProfMode1( SGS_PROF )
{
	P->keytmp = membuf_create();
	P->timetmp = membuf_create();
	ht_init( &P->timings, P->C, 4 );
	sgs_SetHookFunc( P->C, mode1hook, P );
	return 1;
}

static void freeProfMode1( SGS_PROF )
{
	HTPair* p, *pend;
	membuf_destroy( &P->keytmp, P->C );
	membuf_destroy( &P->timetmp, P->C );
	p = P->timings.pairs;
	pend = p + P->timings.size;
	while( p < pend )
	{
		if( p->str )
			sgs_Free( P->C, p->ptr );
		p++;
	}
	ht_free( &P->timings, P->C );
}

static int dpm1sf( const void* p1, const void* p2 )
{
	const HTPair* v1 = *(const HTPair**) p1;
	const HTPair* v2 = *(const HTPair**) p2;
	int cmpsz = v1->size < v2->size ? v1->size : v2->size;
	int ret = memcmp( v1->str, v2->str, cmpsz );
	if( !ret )
		ret = v1->size - v2->size;
	return ret;
}

static int dumpProfMode1( SGS_PROF )
{
	int i, off = 0;
	HTPair* p, *pend, **pbuf = (HTPair**)
		sgs_Malloc( P->C, sizeof(HTPair*) * P->timings.load );
	
	p = P->timings.pairs;
	pend = p + P->timings.size;
	while( p < pend )
	{
		if( p->str )
			pbuf[ off++ ] = p;
		p++;
	}
	qsort( pbuf, off, sizeof( HTPair* ), dpm1sf );
	
	sgs_Writef( P->C, "--- Time by call stack frame ---\n" );
	for( i = 0; i < off; ++i )
	{
		const char *s, *send;
		p = pbuf[ i ];
		s = p->str;
		send = s + p->size;
		while( s < send )
		{
			if( s != p->str )
				sgs_Writef( P->C, "::" );
			sgs_Writef( P->C, "%s", s );
			s += strlen( s ) + 1;
		}
		sgs_Writef( P->C, " - %f\n", AS_DOUBLE( p->ptr ) );
	}
	sgs_Writef( P->C, "---\n" );
	sgs_Free( P->C, pbuf );
	
	return 1;
}
<commit_msg>fixed profiler's hash table usage (untested)<commit_after>

#define SGS_INTERNAL
#include <sgs_int.h>

#include "sgs_prof.h"



static void mode1hook( void* userdata, SGS_CTX, int evid )
{
	SGS_PROF = (sgs_Prof*) userdata;
	double TM = sgs_GetTime();
	if( P->hfn )
		P->hfn( P->hctx, C, evid );

	if( evid == SGS_HOOK_ENTER )
	{
		const char* fname = "<error>";
		sgs_StackFrame* sf = sgs_GetFramePtr( C, 1 );
		sgs_StackFrameInfo( C, sf, &fname, NULL, NULL );
		membuf_appbuf( &P->keytmp, C, fname, strlen( fname ) );
		membuf_appchr( &P->keytmp, C, 0 );
		membuf_appbuf( &P->timetmp, C, &TM, sizeof(TM) );
	}
	else if( evid == SGS_HOOK_EXIT && P->keytmp.size )
	{
		double prevTM;
		HTPair* pair;
		int prevzeroat = P->keytmp.size - 1;
		while( prevzeroat --> 0 )
			if( P->keytmp.ptr[ prevzeroat ] == 0 )
				break;

		prevTM = AS_DOUBLE( P->timetmp.ptr + P->timetmp.size - sizeof(double) );
		pair = ht_find( &P->timings, P->keytmp.ptr, P->keytmp.size,
			sgs_HashFunc( P->keytmp.ptr, P->keytmp.size ) );
		if( pair )
		{
			AS_DOUBLE( pair->ptr ) += TM - prevTM;
		}
		else
		{
			double* val = sgs_Alloc( double );
			*val = TM - prevTM;
			ht_set( &P->timings, C, P->keytmp.ptr, P->keytmp.size, val );
		}


		membuf_resize( &P->keytmp, C, prevzeroat ? prevzeroat + 1 : 0 );
		membuf_resize( &P->timetmp, C, P->timetmp.size - sizeof(TM) );
	}
}

static int initProfMode1( SGS_PROF )
{
	P->keytmp = membuf_create();
	P->timetmp = membuf_create();
	ht_init( &P->timings, P->C, 4 );
	sgs_SetHookFunc( P->C, mode1hook, P );
	return 1;
}

static void freetimingsfunc( HTPair* pair, void* userdata )
{
	SGS_CTX = (sgs_Context*) userdata;
	sgs_Dealloc( pair->ptr );
}

static void freeProfMode1( SGS_PROF )
{
	membuf_destroy( &P->keytmp, P->C );
	membuf_destroy( &P->timetmp, P->C );
	ht_iterate( &P->timings, freetimingsfunc, P->C );
	ht_free( &P->timings, P->C );
}

static int dpm1sf( const void* p1, const void* p2 )
{
	const HTPair* v1 = *(const HTPair**) p1;
	const HTPair* v2 = *(const HTPair**) p2;
	int cmpsz = v1->size < v2->size ? v1->size : v2->size;
	int ret = memcmp( v1->str, v2->str, cmpsz );
	if( !ret )
		ret = v1->size - v2->size;
	return ret;
}


struct dtf_clos
{
	HTPair** arr;
	int* off;
};
static void dumptimingsfunc( HTPair* p, void* userdata )
{
	struct dtf_clos* D = (struct dtf_clos*) userdata;
	D->arr[ (*D->off)++ ] = p;
}

static int dumpProfMode1( SGS_PROF )
{
	int i, off = 0;
	HTPair **pbuf = (HTPair**)
		sgs_Malloc( P->C, sizeof(HTPair*) * P->timings.load );
	
	struct dtf_clos D = { pbuf, &off };
	ht_iterate( &P->timings, dumptimingsfunc, &D );
	
	qsort( pbuf, off, sizeof( HTPair* ), dpm1sf );
	
	sgs_Writef( P->C, "--- Time by call stack frame ---\n" );
	for( i = 0; i < off; ++i )
	{
		const char *s, *send;
		HTPair* p = pbuf[ i ];
		s = p->str;
		send = s + p->size;
		while( s < send )
		{
			if( s != p->str )
				sgs_Writef( P->C, "::" );
			sgs_Writef( P->C, "%s", s );
			s += strlen( s ) + 1;
		}
		sgs_Writef( P->C, " - %f\n", AS_DOUBLE( p->ptr ) );
	}
	sgs_Writef( P->C, "---\n" );
	sgs_Free( P->C, pbuf );
	
	return 1;
}

{'fraction_non_alphanumeric': 0.19656102494942684, 'fraction_numerical': 0.011463250168577209, 'mean_word_length': 3.0889042039972434, 'pattern_counts': {'":': 2, '<': 15, '<?xml version=': 0, '>': 131, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4959998', 'n_tokens_mistral': 2895, 'n_tokens_neox': 2724, 'n_words': 632}