Skip to content

Commit

Permalink
perf: pl_ds.h modulo optimization
Browse files Browse the repository at this point in the history
Co-authored-by: Quattro <quattromusicofficial@gmail.com>
  • Loading branch information
hoffstadt and QuattroMusic committed Nov 11, 2024
1 parent 7d7858e commit 334434c
Showing 1 changed file with 47 additions and 18 deletions.
65 changes: 47 additions & 18 deletions libs/pl_ds.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
*/

// library version (format XYYZZ)
#define PL_DS_VERSION "1.0.0"
#define PL_DS_VERSION_NUM 10000
#define PL_DS_VERSION "1.1.0"
#define PL_DS_VERSION_NUM 10100

/*
Index of this file:
// [SECTION] documentation
// [SECTION] revisions
// [SECTION] header mess
// [SECTION] includes
// [SECTION] forward declarations
Expand Down Expand Up @@ -176,11 +177,20 @@ COMPILE TIME OPTIONS
PL_DS_ALLOC(x)
PL_DS_FREE(x)
* Change initial hashmap size:
PL_DS_HASHMAP_INITIAL_SIZE (default is 256)
PL_DS_HASHMAP_INITIAL_SIZE (default is 256) // should be power of 2
* Change assert by defining:
PL_DS_ASSERT(x)
*/

//-----------------------------------------------------------------------------
// [SECTION] revisions
//-----------------------------------------------------------------------------

/*
1.1 (2024-11) optimization
1.0 (2024-09) stable
*/

//-----------------------------------------------------------------------------
// [SECTION] header mess
//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -430,10 +440,21 @@ typedef struct plHashMap
static inline uint64_t pl__hm_lookup (plHashMap** ptHashMap, uint64_t ulKey);
static inline uint64_t pl__hm_get_free_index(plHashMap** ptHashMap);
static inline bool pl__hm_has_key (plHashMap** pptHashMap, uint64_t ulKey);
static inline void pl__hm_resize (plHashMap** pptHashMap, uint32_t uBucketCount, const char* pcFile, int iLine);
static inline void pl__hm_free (plHashMap** pptHashMap) { pl__hm_resize(pptHashMap, 0, "", 0);}
static inline void pl__hm_insert (plHashMap** pptHashMap, uint64_t ulKey, uint64_t ulValue, const char* pcFile, int iLine);
static inline void pl__hm_remove (plHashMap** pptHashMap, uint64_t ulKey);
static inline void pl__hm_resize (plHashMap** pptHashMap, uint32_t uBucketCount, const char* pcFile, int iLine);
static inline void pl__hm_free (plHashMap** pptHashMap) { pl__hm_resize(pptHashMap, 0, "", 0);}
static inline void pl__hm_insert (plHashMap** pptHashMap, uint64_t ulKey, uint64_t ulValue, const char* pcFile, int iLine);
static inline void pl__hm_remove (plHashMap** pptHashMap, uint64_t ulKey);

static inline size_t
pl__ds_get_next_power_of_2(size_t n)
{
size_t ulResult = 1;
if (n && !(n & (n - 1)))
ulResult = n;
while (ulResult < n)
ulResult <<= 1;
return ulResult;
}

static inline void
pl__hm_resize(plHashMap** pptHashMap, uint32_t uBucketCount, const char* pcFile, int iLine)
Expand All @@ -454,7 +475,9 @@ pl__hm_resize(plHashMap** pptHashMap, uint32_t uBucketCount, const char* pcFile,
uint64_t* sbulOldValueIndices = ptHashMap->_aulValueIndices;
uint64_t* aulOldKeys = ptHashMap->_aulKeys;

ptHashMap->_uBucketCount = uBucketCount < PL_DS_HASHMAP_INITIAL_SIZE ? PL_DS_HASHMAP_INITIAL_SIZE : uBucketCount;

ptHashMap->_uBucketCount = uBucketCount < PL_DS_HASHMAP_INITIAL_SIZE ? PL_DS_HASHMAP_INITIAL_SIZE : (uint32_t)pl__ds_get_next_power_of_2(uBucketCount);

if(uBucketCount > 0)
{

Expand All @@ -463,14 +486,16 @@ pl__hm_resize(plHashMap** pptHashMap, uint32_t uBucketCount, const char* pcFile,
memset(ptHashMap->_aulValueIndices, 0xff, sizeof(uint64_t) * ptHashMap->_uBucketCount);
memset(ptHashMap->_aulKeys, 0xff, sizeof(uint64_t) * ptHashMap->_uBucketCount);

uint64_t mask = uOldBucketCount - 1;

for(uint32_t i = 0; i < uOldBucketCount; i++)
{
const uint64_t ulKey = aulOldKeys[i];
uint64_t ulOldModKey = ulKey % uOldBucketCount;
uint64_t ulOldModKey = ulKey & mask;


while(aulOldKeys[ulOldModKey] != ulKey && aulOldKeys[ulOldModKey] != UINT64_MAX)
ulOldModKey = (ulOldModKey + 1) % uOldBucketCount;
ulOldModKey = (ulOldModKey + 1) & mask;

const uint64_t ulValue = sbulOldValueIndices[ulOldModKey];
ptHashMap->_uItemCount--;
Expand Down Expand Up @@ -518,11 +543,12 @@ pl__hm_insert(plHashMap** pptHashMap, uint64_t ulKey, uint64_t ulValue, const ch
else if(((float)ptHashMap->_uItemCount / (float)ptHashMap->_uBucketCount) > 0.60f)
pl__hm_resize(pptHashMap, ptHashMap->_uBucketCount * 2, pcFile, iLine);

uint64_t ulModKey = ulKey % ptHashMap->_uBucketCount;
uint64_t mask = ptHashMap->_uBucketCount - 1;
uint64_t ulModKey = ulKey & mask;

while(ptHashMap->_aulKeys[ulModKey] != ulKey && ptHashMap->_aulKeys[ulModKey] != UINT64_MAX)
{
ulModKey = (ulModKey + 1) % ptHashMap->_uBucketCount;
ulModKey = (ulModKey + 1) & mask;
if(ptHashMap->_aulKeys[ulModKey] == UINT64_MAX - 1)
break;
}
Expand All @@ -538,10 +564,11 @@ pl__hm_remove(plHashMap** pptHashMap, uint64_t ulKey)
plHashMap* ptHashMap = *pptHashMap;
PL_DS_ASSERT(ptHashMap->_uBucketCount > 0 && "hashmap has no items");

uint64_t ulModKey = ulKey % ptHashMap->_uBucketCount;
uint64_t mask = ptHashMap->_uBucketCount - 1;
uint64_t ulModKey = ulKey & mask;

while(ptHashMap->_aulKeys[ulModKey] != ulKey && ptHashMap->_aulKeys[ulModKey] != UINT64_MAX)
ulModKey = (ulModKey + 1) % ptHashMap->_uBucketCount;
ulModKey = (ulModKey + 1) & mask;

const uint64_t ulValue = ptHashMap->_aulValueIndices[ulModKey];
pl_sb_push(ptHashMap->_sbulFreeIndices, ulValue);
Expand Down Expand Up @@ -624,10 +651,11 @@ pl__hm_lookup(plHashMap** pptHashMap, uint64_t ulKey)
if(ptHashMap->_uBucketCount == 0)
return UINT64_MAX;

uint64_t ulModKey = ulKey % ptHashMap->_uBucketCount;
uint64_t mask = ptHashMap->_uBucketCount - 1;
uint64_t ulModKey = ulKey & mask;

while(ptHashMap->_aulKeys[ulModKey] != ulKey && ptHashMap->_aulKeys[ulModKey] != UINT64_MAX)
ulModKey = (ulModKey + 1) % ptHashMap->_uBucketCount;
ulModKey = (ulModKey + 1) & mask;

if(ptHashMap->_aulKeys[ulModKey] == UINT64_MAX)
return UINT64_MAX;
Expand Down Expand Up @@ -661,10 +689,11 @@ pl__hm_has_key(plHashMap** pptHashMap, uint64_t ulKey)
if(ptHashMap->_uItemCount == 0)
return false;

uint64_t ulModKey = ulKey % ptHashMap->_uBucketCount;
uint64_t mask = ptHashMap->_uBucketCount - 1;
uint64_t ulModKey = ulKey & mask;

while(ptHashMap->_aulKeys[ulModKey] != ulKey && ptHashMap->_aulKeys[ulModKey] != UINT64_MAX)
ulModKey = (ulModKey + 1) % ptHashMap->_uBucketCount;
ulModKey = (ulModKey + 1) & mask;

return ptHashMap->_aulKeys[ulModKey] != UINT64_MAX;
}
Expand Down

0 comments on commit 334434c

Please sign in to comment.