From: hgn Date: Sun, 29 Jun 2025 13:01:25 +0000 (+0100) Subject: KV X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;h=f4c3830d074cebfd9f2dab2796c0a1f1e8a88287;p=vg.git KV --- diff --git a/vg_build.h b/vg_build.h index c34f393..4026690 100644 --- a/vg_build.h +++ b/vg_build.h @@ -282,7 +282,6 @@ vg_compiler_run( struct vg_project *project, vg_strcat( &cmd, " -Wall -ferror-limit=10\\\n" " -Wno-unused-function -Wno-unused-variable\\\n" " -Wno-unused-command-line-argument -Wno-unused-but-set-variable\\\n" - " -Wunused-result\\\n" ); if( env->compiler != k_compiler_clang ) diff --git a/vg_bvh.c b/vg_bvh.c index 05edae7..9127be5 100644 --- a/vg_bvh.c +++ b/vg_bvh.c @@ -104,7 +104,7 @@ bh_tree *bh_create( vg_stack_allocator *stack, bh_system *system, void *user, u3 totsize = sizeof(bh_tree) + sizeof(bh_node) * bh->node_count; - if( stack ) vg_stack_resize_last( stack, totsize ); + if( stack ) bh = vg_stack_resize_last( stack, totsize ); else bh = vg_realloc( bh, totsize ); vg_success( "BVH done, size: %u/%u\n", bh->node_count, (alloc_count*2-1) ); diff --git a/vg_io.c b/vg_io.c index a293958..e759572 100644 --- a/vg_io.c +++ b/vg_io.c @@ -208,7 +208,7 @@ void *vg_file_read( vg_stack_allocator *stack, const char *path, u32 *size, bool /* read in chunks */ for( u32 i=0; 1; i++ ) { - vg_stack_extend_last( stack, VG_FILE_IO_CHUNK_SIZE ); + buffer = vg_stack_extend_last( stack, VG_FILE_IO_CHUNK_SIZE ); u64 l = fread( buffer + current, 1, VG_FILE_IO_CHUNK_SIZE, f ); current += l; @@ -238,11 +238,11 @@ void *vg_file_read( vg_stack_allocator *stack, const char *path, u32 *size, bool if( text ) { - vg_stack_extend_last( stack, 1 ); + buffer = vg_stack_extend_last( stack, 1 ); buffer[ current ++ ] = '\0'; } - vg_stack_resize_last( stack, current ); + buffer = vg_stack_resize_last( stack, current ); fclose( f ); *size = (u32)current; diff --git a/vg_kv.c b/vg_kv.c index 39f7831..a4d8388 100644 --- a/vg_kv.c +++ b/vg_kv.c @@ -1,3 +1,268 @@ #include "vg_kv.h" +void vg_kv_parse( vg_kvs *out_kvs, const char *source, vg_stack_allocator *stack ) +{ + out_kvs->source_buffer = source; + out_kvs->kv_count = 1; + out_kvs->kvs = vg_stack_allocate( stack, sizeof(vg_kv), 8, "KV Metadata buffer" ); + vg_zero_mem( out_kvs->kvs, sizeof(vg_kv) ); + u32 token_start=0, + token_length=0, + token_hash=0, + depth=0; + char delim = 0; + + struct + { + u32 frame_id, latest_child_id; + } + frame_stack[ 64 ]; + frame_stack[0].frame_id = 0; + frame_stack[0].latest_child_id = 0; + + u32 t0_start=0, t0_length=0, t0_hash=0; + + for( u32 i=0; i<0xffffffff; i ++ ) + { + out_kvs->source_length = i; + + char c = source[i]; + if( c == '\0' ) + break; + + u32 link_id = 0, link_depth = 0; + + if( (delim && (c == delim)) || (!delim && (c==' '||c=='\t'||c=='\r'||c=='\n'||c=='{'||c=='}')) ) + { + if( token_length ) + { + token_length --; + if( t0_length ) + { + /* pair */ + link_id = out_kvs->kv_count ++; + link_depth = depth; + + out_kvs->kvs = vg_stack_extend_last( stack, sizeof(vg_kv) ); + vg_kv *kv = &out_kvs->kvs[ link_id ]; + kv->key_info = (0xFFFFF & t0_hash) | (0x3FF & t0_length)<<20 | (0x1) << 30; + kv->key_offset = t0_start; + kv->brother_offset = 0; /* deffered */ + kv->value.offset_from_key = token_start - t0_start; + kv->value.length = token_length; + + t0_length = 0; + } + else + { + t0_start = token_start; + t0_length = token_length; + t0_hash = token_hash; + } + + token_length = 0; + } + + if( c=='{'||c=='}'||c=='\n' ) + { + /* SYNTAX TOKEN */ + if( c == '{' ) + { + link_id = out_kvs->kv_count ++; + link_depth = depth; + + out_kvs->kvs = vg_stack_extend_last( stack, sizeof(vg_kv) ); + vg_kv *kv = &out_kvs->kvs[ link_id ]; + kv->brother_offset = 0; /* deffered */ + kv->children = 0; + if( t0_length ) + { + /* frame with name */ + kv->key_info = (0xFFFFF & t0_hash) | (0x3FF & t0_length) << 20; + kv->key_offset = t0_start; + } + else + { + /* frame with no name */ + kv->key_info = 5381; + kv->key_offset = 0; + } + + t0_length = 0; + depth ++; + frame_stack[ depth ].latest_child_id = 0; + frame_stack[ depth ].frame_id = link_id; + } + else if( c == '}' ) + { + if( depth ) + depth --; + t0_length = 0; + } + } + + delim = 0; + } + else + { + if( token_length ) + { + token_length ++; + token_hash = ((token_hash << 5) + token_hash) + (u32)c; + } + else + { + if( c=='"'||c=='\'' ) + { + delim = c; + token_start = i+1; + token_length = 1; + token_hash = 5381; + } + else + { + token_start = i; + token_length = 2; + token_hash = ((5381<<5)+5381) + (u32)c; + } + } + } + + if( link_id ) + { + u32 parent_id = frame_stack[link_depth].frame_id; + vg_kv *parent = &out_kvs->kvs[ parent_id ]; + parent->children ++; + + u32 brother_id = frame_stack[link_depth].latest_child_id; + if( brother_id ) + { + vg_kv *brother = &out_kvs->kvs[ brother_id ]; + VG_ASSERT( brother->brother_offset == 0 ); + brother->brother_offset = link_id - brother_id; + } + frame_stack[ link_depth ].latest_child_id = link_id; + } + } +} + +u32 vg_kv_type( vg_kvs *kvs, u32 kv_id ){ return (kvs->kvs[ kv_id ].key_info >> 30) & 0x3; } + +const char *vg_kv_key( vg_kvs *kvs, u32 kv_id, u32 *out_length ) +{ + vg_kv *kv = &kvs->kvs[ kv_id ]; + *out_length = (kv->key_info >> 20) & 0x3FF; + return kvs->source_buffer + kv->key_offset; +} + +const char *vg_kv_value( vg_kvs *kvs, u32 kv_id, u32 *out_length ) +{ + u32 type = vg_kv_type( kvs, kv_id ); + if( type == 0x0 ) + return NULL; + else + { + vg_kv *kv = &kvs->kvs[ kv_id ]; + *out_length = kv->value.length; + return kvs->source_buffer + (kv->key_offset + kv->value.offset_from_key); + } +} + +u32 vg_kv_child_count( vg_kvs *kvs, u32 kv_id ) +{ + u32 type = vg_kv_type( kvs, kv_id ); + if( type == 0x0 ) + return kvs->kvs[ kv_id ].children; + else + return 0; +} + +u32 vg_kv_child( vg_kvs *kvs, u32 root_id, u32 index ) +{ + VG_ASSERT( index == 0 ); + + if( vg_kv_child_count( kvs, root_id ) ) + return root_id +1; + else + return 0; +} + +u32 vg_kv_next( vg_kvs *kvs, u32 kv_id ) +{ + u32 offset = kvs->kvs[ kv_id ].brother_offset; + if( offset ) + return kv_id + offset; + else + return 0; +} + +u32 vg_kv_find( vg_kvs *kvs, u32 root_id, const char *key ) +{ + u32 hash = vg_strdjb2( key ); + u32 child_id = vg_kv_child( kvs, root_id, 0 ); + while( child_id ) + { + vg_kv *kv = &kvs->kvs[ child_id ]; + if( ((kv->key_info ^ hash) & 0xFFFFF) == 0 ) + { + u32 key_length; + const char *child_key = vg_kv_key( kvs, child_id, &key_length ); + if( child_key ) + { + for( u32 i=0; ikv_count * sizeof(vg_kv)) / (f32)kvs->source_length )*100.0f ); +} + +void vg_kv_print_tree( vg_kvs *kvs, u32 root_id, u32 depth ) +{ + VG_ASSERT( vg_kv_type( kvs, root_id ) == 0x0 ); + + const char *k_whitespace = " "; + + u32 root_len; + const char *root_str = vg_kv_key( kvs, root_id, &root_len ); + vg_info( "%.*s\"%.*s\"\n", depth*2, k_whitespace, root_len, root_str ); + vg_info( "%.*s{\n", depth*2, k_whitespace ); + depth ++; + + u32 child_id = vg_kv_child( kvs, root_id, 0 ); + while( child_id ) + { + if( vg_kv_type( kvs, child_id ) == 0x0 ) + vg_kv_print_tree( kvs, child_id, depth ); + else + { + u32 key_len; + const char *key_str = vg_kv_key( kvs, child_id, &key_len ); + + u32 value_len; + const char *value_str = vg_kv_value( kvs, child_id, &value_len ); + + if( key_str && value_str ) + vg_info( "%.*s\"%.*s\" \"%.*s\"\n", depth*2, k_whitespace, key_len, key_str, value_len, value_str ); + else + vg_error( "%.*s\n", depth*2, k_whitespace ); + } + + child_id = vg_kv_next( kvs, child_id ); + } + + depth --; + vg_info( "%.*s}\n", depth*2, k_whitespace ); +} diff --git a/vg_kv.h b/vg_kv.h index ee11558..0e0214d 100644 --- a/vg_kv.h +++ b/vg_kv.h @@ -1,11 +1,22 @@ #pragma once #include "vg_platform.h" +typedef struct vg_kvs vg_kvs; +typedef struct vg_kv vg_kv; +struct vg_kvs +{ + const char *source_buffer; + u32 source_length; + + vg_kv *kvs; + u32 kv_count; +}; + struct vg_kv { u32 key_info; /* 20 bit hash, 10 bit key length, 2 bit type */ - u32 key_offset; /* into the raw text buffer */ - u32 brother_offset;/* 24 bits, relative jump past all descendents to the next key */ + u32 key_offset; /* 32 bit, indexes into the raw text buffer */ + u32 brother_offset;/* 24 bits, relative jump past all descendents to the next key. If 0, no brothers */ union { diff --git a/vg_mem.c b/vg_mem.c index 2e69ad6..fe93cca 100644 --- a/vg_mem.c +++ b/vg_mem.c @@ -170,7 +170,7 @@ void vg_stack_set_flags_last( vg_stack_allocator *stack, u16 append_flags ) meta->flags |= append_flags; } -void vg_stack_resize_last( vg_stack_allocator *stack, u32 new_size ) +void *vg_stack_resize_last( vg_stack_allocator *stack, u32 new_size ) { u32 base_offset = stack->used - stack->last_allocation_totalsize, block_size = new_size; @@ -186,14 +186,15 @@ void vg_stack_resize_last( vg_stack_allocator *stack, u32 new_size ) vg_stack_growmaybe( stack, new_usage ); stack->used = new_usage; stack->last_allocation_totalsize = block_size; + return stack->data + (new_usage - new_size); } -void vg_stack_extend_last( vg_stack_allocator *stack, u32 extra_bytes ) +void *vg_stack_extend_last( vg_stack_allocator *stack, u32 extra_bytes ) { u32 current_size = stack->last_allocation_totalsize; if( stack->flags & VG_STACK_ALLOCATOR_METADATA ) current_size -= sizeof(vg_allocation_meta); - vg_stack_resize_last( stack, current_size + extra_bytes ); + return vg_stack_resize_last( stack, current_size + extra_bytes ); } void *vg_stack_pop_last( vg_stack_allocator *stack ) diff --git a/vg_mem.h b/vg_mem.h index 9c91111..34dbe59 100644 --- a/vg_mem.h +++ b/vg_mem.h @@ -67,8 +67,11 @@ vg_stack_allocator *vg_stack_make_substack( vg_stack_allocator *parent, u32 capa #define VG_STACK_ALLOCATE_STRUCT( STACK, STRUCT ) vg_stack_allocate( STACK, sizeof(STRUCT), alignof(STRUCT), NULL ) -void vg_stack_resize_last( vg_stack_allocator *stack, u32 new_size ); -void vg_stack_extend_last( vg_stack_allocator *stack, u32 extra_bytes ); +__attribute__((warn_unused_result)) +void *vg_stack_resize_last( vg_stack_allocator *stack, u32 new_size ); + +__attribute__((warn_unused_result)) +void *vg_stack_extend_last( vg_stack_allocator *stack, u32 extra_bytes ); /* * The following are availible if allocator has the flag METADATA set