added clang-format

This commit is contained in:
2023-02-09 12:32:48 -06:00
committed by cpunch
parent 88284a0b6e
commit 6056f8eb5b
25 changed files with 2894 additions and 2301 deletions

View File

@@ -1,21 +1,25 @@
#include "ctable.h"
#include "cmem.h"
#include "cvalue.h"
#include "cobj.h"
#include "cvalue.h"
#include <string.h>
#define MAX_TABLE_FILL 0.75
#define MAX_TABLE_FILL 0.75
// at 30% capacity with capacity > ARRAY_START, shrink the array
#define MIN_TABLE_CAPACITY ARRAY_START
// bit-twiddling hacks, gets the next power of 2
unsigned int nextPow2(unsigned int x) {
if (x <= ARRAY_START - 1) return ARRAY_START; // sanity check
unsigned int nextPow2(unsigned int x)
{
if (x <= ARRAY_START - 1)
return ARRAY_START; // sanity check
x--;
int power = 2;
while (x >>= 1) power <<= 1;
while (x >>= 1)
power <<= 1;
if (power < ARRAY_START)
return ARRAY_START;
@@ -23,7 +27,8 @@ unsigned int nextPow2(unsigned int x) {
return power;
}
void cosmoT_initTable(CState *state, CTable *tbl, int startCap) {
void cosmoT_initTable(CState *state, CTable *tbl, int startCap)
{
startCap = startCap != 0 ? startCap : ARRAY_START; // sanity check :P
tbl->capacityMask = startCap - 1;
@@ -39,7 +44,8 @@ void cosmoT_initTable(CState *state, CTable *tbl, int startCap) {
}
}
void cosmoT_addTable(CState *state, CTable *from, CTable *to) {
void cosmoT_addTable(CState *state, CTable *from, CTable *to)
{
int cap = from->capacityMask + 1;
for (int i = 0; i < cap; i++) {
CTableEntry *entry = &from->table[i];
@@ -51,44 +57,50 @@ void cosmoT_addTable(CState *state, CTable *from, CTable *to) {
}
}
void cosmoT_clearTable(CState *state, CTable *tbl) {
void cosmoT_clearTable(CState *state, CTable *tbl)
{
cosmoM_freearray(state, CTableEntry, tbl->table, (tbl->capacityMask + 1));
}
uint32_t getObjectHash(CObj *obj) {
switch(obj->type) {
case COBJ_STRING:
return ((CObjString*)obj)->hash;
default:
return (uint32_t)obj; // just "hash" the pointer
uint32_t getObjectHash(CObj *obj)
{
switch (obj->type) {
case COBJ_STRING:
return ((CObjString *)obj)->hash;
default:
return (uint32_t)obj; // just "hash" the pointer
}
}
uint32_t getValueHash(CValue *val) {
uint32_t getValueHash(CValue *val)
{
switch (GET_TYPE(*val)) {
case COSMO_TREF:
return getObjectHash(cosmoV_readRef(*val));
case COSMO_TNUMBER: {
uint32_t buf[sizeof(cosmo_Number)/sizeof(uint32_t)];
cosmo_Number num = cosmoV_readNumber(*val);
case COSMO_TREF:
return getObjectHash(cosmoV_readRef(*val));
case COSMO_TNUMBER: {
uint32_t buf[sizeof(cosmo_Number) / sizeof(uint32_t)];
cosmo_Number num = cosmoV_readNumber(*val);
if (num == 0)
return 0;
memcpy(buf, &num, sizeof(buf));
for (size_t i = 0; i < sizeof(cosmo_Number)/sizeof(uint32_t); i++) buf[0] += buf[i];
return buf[0];
}
// TODO: add support for other types
default:
if (num == 0)
return 0;
memcpy(buf, &num, sizeof(buf));
for (size_t i = 0; i < sizeof(cosmo_Number) / sizeof(uint32_t); i++)
buf[0] += buf[i];
return buf[0];
}
// TODO: add support for other types
default:
return 0;
}
}
// mask should always be (capacity - 1)
static CTableEntry *findEntry(CState *state, CTableEntry *entries, int mask, CValue key) {
static CTableEntry *findEntry(CState *state, CTableEntry *entries, int mask, CValue key)
{
uint32_t hash = getValueHash(&key);
uint32_t indx = hash & mask; // since we know the capacity will *always* be a power of 2, we can use bitwise & to perform a MUCH faster mod operation
uint32_t indx = hash & mask; // since we know the capacity will *always* be a power of 2, we can
// use bitwise & to perform a MUCH faster mod operation
CTableEntry *tomb = NULL;
// keep looking for an open slot in the entries array
@@ -112,17 +124,19 @@ static CTableEntry *findEntry(CState *state, CTableEntry *entries, int mask, CVa
}
}
static void resizeTbl(CState *state, CTable *tbl, int newCapacity, bool canShrink) {
static void resizeTbl(CState *state, CTable *tbl, int newCapacity, bool canShrink)
{
if (canShrink && cosmoT_checkShrink(state, tbl))
return;
size_t size = sizeof(CTableEntry) * newCapacity;
int cachedCount = tbl->count;
int newCount, oldCap;
cosmoM_checkGarbage(state, size); // if this allocation would cause a GC, run the GC
if (tbl->count < cachedCount) // the GC removed some objects from this table and resized it, ignore our resize event!
if (tbl->count < cachedCount) // the GC removed some objects from this table and resized it,
// ignore our resize event!
return;
CTableEntry *entries = cosmoM_xmalloc(state, size);
@@ -157,10 +171,14 @@ static void resizeTbl(CState *state, CTable *tbl, int newCapacity, bool canShrin
tbl->tombstones = 0;
}
bool cosmoT_checkShrink(CState *state, CTable *tbl) {
// if count > 8 and active entries < tombstones
if (tbl->count > MIN_TABLE_CAPACITY && (tbl->count - tbl->tombstones < tbl->tombstones || tbl->tombstones > 50)) { // TODO: 50 should be a threshhold
resizeTbl(state, tbl, nextPow2(tbl->count - tbl->tombstones) * GROW_FACTOR, false); // shrink based on active entries to the next pow of 2
bool cosmoT_checkShrink(CState *state, CTable *tbl)
{
// if count > 8 and active entries < tombstones
if (tbl->count > MIN_TABLE_CAPACITY &&
(tbl->count - tbl->tombstones < tbl->tombstones ||
tbl->tombstones > 50)) { // TODO: 50 should be a threshhold
resizeTbl(state, tbl, nextPow2(tbl->count - tbl->tombstones) * GROW_FACTOR,
false); // shrink based on active entries to the next pow of 2
return true;
}
@@ -168,7 +186,8 @@ bool cosmoT_checkShrink(CState *state, CTable *tbl) {
}
// returns a pointer to the allocated value
COSMO_API CValue* cosmoT_insert(CState *state, CTable *tbl, CValue key) {
COSMO_API CValue *cosmoT_insert(CState *state, CTable *tbl, CValue key)
{
// make sure we have enough space allocated
int cap = tbl->capacityMask + 1;
if (tbl->count + 1 > (int)(cap * MAX_TABLE_FILL)) {
@@ -178,7 +197,8 @@ COSMO_API CValue* cosmoT_insert(CState *state, CTable *tbl, CValue key) {
}
// insert into the table
CTableEntry *entry = findEntry(state, tbl->table, tbl->capacityMask, key); // -1 for our capacity mask
CTableEntry *entry =
findEntry(state, tbl->table, tbl->capacityMask, key); // -1 for our capacity mask
if (IS_NIL(entry->key)) {
if (IS_NIL(entry->val)) // is it empty?
@@ -191,22 +211,25 @@ COSMO_API CValue* cosmoT_insert(CState *state, CTable *tbl, CValue key) {
return &entry->val;
}
bool cosmoT_get(CState *state, CTable *tbl, CValue key, CValue *val) {
bool cosmoT_get(CState *state, CTable *tbl, CValue key, CValue *val)
{
// sanity check
if (tbl->count == 0) {
*val = cosmoV_newNil();
return false;
}
CTableEntry *entry = findEntry(state, tbl->table, tbl->capacityMask, key);
*val = entry->val;
// return if get was successful
return !(IS_NIL(entry->key));
}
bool cosmoT_remove(CState* state, CTable *tbl, CValue key) {
if (tbl->count == 0) return 0; // sanity check
bool cosmoT_remove(CState *state, CTable *tbl, CValue key)
{
if (tbl->count == 0)
return 0; // sanity check
CTableEntry *entry = findEntry(state, tbl->table, tbl->capacityMask, key);
if (IS_NIL(entry->key)) // sanity check
@@ -214,20 +237,26 @@ bool cosmoT_remove(CState* state, CTable *tbl, CValue key) {
// crafts tombstone
entry->key = cosmoV_newNil(); // this has to be nil
entry->val = cosmoV_newBoolean(false); // doesn't really matter what this is, as long as it isn't nil
entry->val =
cosmoV_newBoolean(false); // doesn't really matter what this is, as long as it isn't nil
tbl->tombstones++;
return true;
}
// returns the active entry count
COSMO_API int cosmoT_count(CTable *tbl) {
COSMO_API int cosmoT_count(CTable *tbl)
{
return tbl->count - tbl->tombstones;
}
CObjString *cosmoT_lookupString(CTable *tbl, const char *str, int length, uint32_t hash) {
if (tbl->count == 0) return 0; // sanity check
uint32_t indx = hash & tbl->capacityMask; // since we know the capacity will *always* be a power of 2, we can use bitwise & to perform a MUCH faster mod operation
CObjString *cosmoT_lookupString(CTable *tbl, const char *str, int length, uint32_t hash)
{
if (tbl->count == 0)
return 0; // sanity check
uint32_t indx =
hash & tbl->capacityMask; // since we know the capacity will *always* be a power of 2, we
// can use bitwise & to perform a MUCH faster mod operation
// keep looking for an open slot in the entries array
while (true) {
@@ -236,9 +265,10 @@ CObjString *cosmoT_lookupString(CTable *tbl, const char *str, int length, uint32
// check if it's an empty slot (meaning we dont have it in the table)
if (IS_NIL(entry->key) && IS_NIL(entry->val)) {
return NULL;
} else if (IS_STRING(entry->key) && cosmoV_readString(entry->key)->length == length && memcmp(cosmoV_readString(entry->key)->str, str, length) == 0) {
} else if (IS_STRING(entry->key) && cosmoV_readString(entry->key)->length == length &&
memcmp(cosmoV_readString(entry->key)->str, str, length) == 0) {
// it's a match!
return (CObjString*)cosmoV_readRef(entry->key);
return (CObjString *)cosmoV_readRef(entry->key);
}
indx = (indx + 1) & tbl->capacityMask; // fast mod here too
@@ -246,7 +276,8 @@ CObjString *cosmoT_lookupString(CTable *tbl, const char *str, int length, uint32
}
// for debugging purposes
void cosmoT_printTable(CTable *tbl, const char *name) {
void cosmoT_printTable(CTable *tbl, const char *name)
{
printf("==== [[%s]] ====\n", name);
int cap = tbl->capacityMask + 1;
for (int i = 0; i < cap; i++) {