#include "daScript/misc/platform.h"
#include "daScript/simulate/runtime_table_nodes.h"
namespace das
{
void table_clear ( Context & context, Table & arr ) {
if ( arr.isLocked() ) context.throw_error("can't clear locked table");
if ( arr.data ) {
memset(arr.hashes, 0, arr.capacity*sizeof(uint64_t));
memset(arr.data, 0, arr.keys - arr.data);
}
arr.size = 0;
}
void table_lock ( Context & context, Table & arr ) {
if ( arr.shared || arr.hopeless ) return;
arr.lock ++;
if ( arr.lock==0 ) context.throw_error("table lock overflow");
}
void table_unlock ( Context & context, Table & arr ) {
if ( arr.shared || arr.hopeless ) return;
if ( arr.lock==0 ) context.throw_error("table lock underflow");
arr.lock --;
}
// TableIterator
size_t TableIterator::nextValid ( size_t index ) const {
for (; index < table->capacity; index++) {
if (table->hashes[index] > HASH_KILLED64) {
break;
}
}
return index;
}
bool TableIterator::first ( Context & context, char * _value ) {
char ** value = (char **)_value;
table_lock(context, *(Table *)table);
data = getData();
table_end = data + table->capacity*stride;
size_t index = nextValid(0);
data += index * stride;
*value = data;
return (bool) table->size;
}
bool TableIterator::next ( Context &, char * _value ) {
char ** value = (char **) _value;
char * tableData = getData();
size_t index = (data-tableData)/stride;
index = nextValid(index + 1);
data = tableData + index * stride;
*value = data;
return data != table_end;
}
void TableIterator::close ( Context & context, char * _value ) {
if ( _value ) {
char ** value = (char **) _value;
*value = nullptr;
}
table_unlock(context, *(Table *)table);
}
// keys and values
char * TableKeysIterator::getData ( ) const {
return table->keys;
}
void TableKeysIterator::close ( Context & context, char * value ) {
TableIterator::close(context,value);
context.heap->free((char *)this, sizeof(TableKeysIterator));
}
char * TableValuesIterator::getData ( ) const {
return table->data;
}
void TableValuesIterator::close ( Context & context, char * value ) {
TableIterator::close(context,value);
context.heap->free((char *)this, sizeof(TableValuesIterator));
}
void builtin_table_keys ( Sequence & result, const Table & tab, int32_t stride, Context * __context__ ) {
char * iter = __context__->heap->allocate(sizeof(TableKeysIterator));
__context__->heap->mark_comment(iter,"table keys iterator");
new (iter) TableKeysIterator(&tab, stride);
result = { (Iterator *) iter };
}
void builtin_table_values ( Sequence & result, const Table & tab, int32_t stride, Context * __context__ ) {
char * iter = __context__->heap->allocate(sizeof(TableKeysIterator));
__context__->heap->mark_comment(iter,"table values iterator");
new (iter) TableValuesIterator(&tab, stride);
result = { (Iterator *) iter };
}
// delete
vec4f SimNode_DeleteTable::eval ( Context & context ) {
DAS_PROFILE_NODE
auto pTable = (Table *) subexpr->evalPtr(context);
pTable = pTable + total - 1;
for ( uint32_t i=0; i!=total; ++i, pTable-- ) {
if ( pTable->data ) {
if ( !pTable->isLocked() ) {
uint32_t oldSize = pTable->capacity*(vts_add_kts + sizeof(uint64_t));
context.heap->free(pTable->data, oldSize);
} else {
context.throw_error("deleting locked table");
return v_zero();
}
}
memset ( pTable, 0, sizeof(Table) );
}
return v_zero();
}
}