13#ifndef MDATA_LOCK_TRACE_LVL
14# define MDATA_LOCK_TRACE_LVL 0
17#ifndef MDATA_STRPOOL_TRACE_LVL
18# define MDATA_STRPOOL_TRACE_LVL 0
21#ifndef MDATA_VECTOR_TRACE_LVL
22# define MDATA_VECTOR_TRACE_LVL 0
25#ifndef MDATA_TABLE_TRACE_LVL
26# define MDATA_TABLE_TRACE_LVL 0
29#ifndef MDATA_TABLE_KEY_SZ_MAX
30# define MDATA_TABLE_KEY_SZ_MAX 8
46#define MDATA_VECTOR_FLAG_REFCOUNT 0x01
48#define MDATA_VECTOR_FLAG_IS_LOCKED 0x02
50#ifndef MDATA_VECTOR_INIT_STEP_SZ
55# define MDATA_VECTOR_INIT_STEP_SZ 10
67#define MDATA_STRPOOL_FLAG_IS_LOCKED 0x01
69#define MDATA_STRPOOL_FLAG_DEDUPE 0x02
71typedef size_t mdata_strpool_idx_t;
134 char string[MDATA_TABLE_KEY_SZ_MAX + 1];
140 volatile uint16_t flags;
158mdata_strpool_idx_t mdata_strpool_find(
168mdata_strpool_idx_t mdata_strpool_append(
169 struct MDATA_STRPOOL* sp,
const char* str,
size_t str_sz, uint8_t flags );
202ssize_t mdata_vector_insert(
236uint32_t mdata_hash(
const char* token,
size_t token_sz );
245 void* cb_data,
size_t cb_data_sz,
size_t idx );
253 mdata_table_iter_t cb,
void* cb_data,
size_t cb_data_sz );
257 void* value,
size_t value_sz );
262void* mdata_table_get_void(
const struct MDATA_TABLE* t,
const char* key );
264void* mdata_table_hash_get_void(
265 struct MDATA_TABLE* t, uint32_t key_hash,
size_t key_sz );
271#if MDATA_LOCK_TRACE_LVL > 0
272# define mdata_debug_lock_printf( fmt, ... ) \
273 debug_printf( MDATA_LOCK_TRACE_LVL, fmt, __VA_ARGS__ );
275# define mdata_debug_lock_printf( fmt, ... )
283#define mdata_strpool_sz( sp ) ((sp)->str_sz_max)
285#define mdata_strpool_is_locked( sp ) \
286 (MDATA_STRPOOL_FLAG_IS_LOCKED == \
287 (MDATA_STRPOOL_FLAG_IS_LOCKED & (sp)->flags))
289#define mdata_strpool_lock( sp ) \
290 mdata_debug_lock_printf( "locking strpool %p...", sp ); \
291 if( NULL != (sp)->str_p ) { \
292 error_printf( "str_p not null! double lock?" ); \
293 retval = MERROR_ALLOC; \
296 maug_mlock( (sp)->str_h, (sp)->str_p ); \
297 maug_cleanup_if_null_lock( char*, (sp)->str_p ); \
298 (sp)->flags |= MDATA_STRPOOL_FLAG_IS_LOCKED;
300#define mdata_strpool_unlock( sp ) \
301 mdata_debug_lock_printf( "unlocking strpool %p...", sp ); \
302 if( NULL != (sp)->str_p ) { \
303 maug_munlock( (sp)->str_h, (sp)->str_p ); \
304 (sp)->flags &= ~MDATA_STRPOOL_FLAG_IS_LOCKED; \
307#define mdata_strpool_get( sp, idx ) \
308 ((idx >= 1 && idx < (sp)->str_sz) ? &((sp)->str_p[idx]) : NULL)
310#define mdata_strpool_get_sz( sp, idx ) \
311 ((idx >= sizeof( size_t ) && idx < (sp)->str_sz) ? \
312 (size_t)(*(&((sp)->str_p[idx - sizeof( size_t )]))) : 0)
314#define mdata_strpool_padding( str_sz ) \
315 (sizeof( size_t ) - ((str_sz + 1 ) % sizeof( size_t )))
332#define mdata_vector_lock( v ) \
333 if( (MAUG_MHANDLE)NULL == (v)->data_h && NULL == (v)->data_bytes ) { \
334 mdata_debug_lock_printf( "locking empty vector..." ); \
335 (v)->flags |= MDATA_VECTOR_FLAG_IS_LOCKED; \
337 mdata_vector_get_flag( v, MDATA_VECTOR_FLAG_REFCOUNT ) && \
341 mdata_debug_lock_printf( "vector " #v " locks: " SSIZE_T_FMT, (v)->locks ); \
344 if( mdata_vector_is_locked( v ) ) { \
345 error_printf( "attempting to double-lock vector!" ); \
346 retval = MERROR_OVERFLOW; \
349 if( (MAUG_MHANDLE)NULL == (v)->data_h ) { \
350 error_printf( "invalid data handle!" ); \
351 retval = MERROR_ALLOC; \
354 maug_mlock( (v)->data_h, (v)->data_bytes ); \
355 maug_cleanup_if_null_lock( uint8_t*, (v)->data_bytes ); \
356 (v)->flags |= MDATA_VECTOR_FLAG_IS_LOCKED; \
357 mdata_debug_lock_printf( "locked vector " #v ); \
365#define mdata_vector_unlock( v ) \
366 if( (MAUG_MHANDLE)NULL == (v)->data_h && NULL == (v)->data_bytes ) { \
367 mdata_debug_lock_printf( "locking empty vector..." ); \
368 (v)->flags &= ~MDATA_VECTOR_FLAG_IS_LOCKED; \
371 mdata_vector_get_flag( v, MDATA_VECTOR_FLAG_REFCOUNT ) && \
375 mdata_debug_lock_printf( "vector " #v " locks: " SSIZE_T_FMT, \
378 if( 0 == (v)->locks && NULL != (v)->data_bytes ) { \
379 assert( mdata_vector_is_locked( v ) ); \
380 maug_munlock( (v)->data_h, (v)->data_bytes ); \
381 (v)->flags &= ~MDATA_VECTOR_FLAG_IS_LOCKED; \
382 mdata_debug_lock_printf( "unlocked vector " #v ); \
386#define mdata_vector_get( v, idx, type ) \
387 ((type*)mdata_vector_get_void( v, idx ))
389#define mdata_vector_get_last( v, type ) \
390 (0 < mdata_vector_ct( v ) ? \
391 ((type*)mdata_vector_get_void( v, \
392 mdata_vector_ct( v ) - 1 )) : NULL)
394#define mdata_vector_remove_last( v ) \
395 (0 < mdata_vector_ct( v ) ? \
396 (mdata_vector_remove( v, mdata_vector_ct( v ) - 1 )) : MERROR_OVERFLOW)
398#define mdata_vector_set_ct_step( v, step ) \
408#define mdata_vector_ct( v ) ((v)->ct)
414#define mdata_vector_sz( v ) (((v)->ct_max) * ((v)->item_sz))
420#define mdata_vector_fill( v, ct_new, sz ) \
421 retval = mdata_vector_alloc( v, sz, ct_new ); \
422 maug_cleanup_if_not_ok(); \
425#define mdata_vector_is_locked( v ) \
426 (MDATA_VECTOR_FLAG_IS_LOCKED == \
427 (MDATA_VECTOR_FLAG_IS_LOCKED & (v)->flags))
430#define mdata_vector_insert_sort( v, i, t, field )
433#define mdata_vector_sort( v, t, field )
435#define _mdata_vector_item_ptr( v, idx ) \
436 (&((v)->data_bytes[((idx) * ((v)->item_sz))]))
438#define mdata_vector_set_flag( v, flag ) (v)->flags |= (flag)
440#define mdata_vector_get_flag( v, flag ) ((flag) == ((v)->flags & (flag)))
449#define mdata_table_is_locked( t ) \
450 (mdata_vector_is_locked( &((t)->data_cols[0]) ))
452#define mdata_table_get( t, key, type ) \
453 ((type*)mdata_table_get_void( t, key ))
455#define mdata_table_hash_get( t, hash, sz, type ) \
456 ((type*)mdata_table_hash_get_void( t, hash, sz ))
458#define mdata_table_ct( t ) ((t)->data_cols[0].ct)
460#define mdata_table_sz( t ) \
461 mdata_vector_sz( &((t)->data_cols[0]) ) + \
462 mdata_vector_sz( &((t)->data_cols[1]) )
466#define mdata_retval( idx ) (0 > idx ? ((idx) * -1) : MERROR_OK)
474 mdata_strpool_idx_t i = 0;
477 if( !mdata_strpool_is_locked( sp ) ) {
478 mdata_strpool_lock( sp );
482 for( i = 0 ; sp->str_sz > i ; i += (size_t)*(&(sp->str_p[i])) ) {
492 mdata_strpool_unlock( sp );
502 char* strpool_p = NULL;
504 maug_mlock( sp->str_h, strpool_p );
506 for( i = 0 ; mdata_strpool_sz( sp ) > i ; i++ ) {
507 printf(
"0x%02x ", strpool_p[i] );
511 if( NULL != strpool_p ) {
512 maug_munlock( sp->str_h, strpool_p );
518mdata_strpool_idx_t mdata_strpool_find(
519 struct MDATA_STRPOOL* strpool,
const char* str,
size_t str_sz
522 mdata_strpool_idx_t i = 0;
523 char* strpool_p = NULL;
524 size_t* p_str_iter_sz = NULL;
526 if( (MAUG_MHANDLE)NULL == strpool->str_h ) {
527 error_printf(
"strpool not allocated!" );
532 maug_mlock( strpool->str_h, strpool_p );
534 while( i < strpool->str_sz ) {
535 p_str_iter_sz = (
size_t*)&(strpool_p[i]);
538 &(strpool_p[i +
sizeof(
size_t )]), str, str_sz + 1 )
541 i +=
sizeof( size_t );
542#if MDATA_STRPOOL_TRACE_LVL > 0
543 debug_printf( MDATA_STRPOOL_TRACE_LVL,
544 "found strpool_idx: " SIZE_T_FMT
" (" SIZE_T_FMT
" bytes): \"%s\" "
545 "to match " SIZE_T_FMT
"-byte token: %s",
546 i, *p_str_iter_sz, &(strpool_p[i]),
551#if MDATA_STRPOOL_TRACE_LVL > 0
553 debug_printf( MDATA_STRPOOL_TRACE_LVL,
554 "skipping strpool_idx: " SIZE_T_FMT
" (" SIZE_T_FMT
556 i +
sizeof(
size_t ), *p_str_iter_sz,
557 &(strpool_p[i +
sizeof(
size_t )]) );
568 if( MERROR_OK != retval ) {
572 if( NULL != strpool_p ) {
573 maug_munlock( strpool->str_h, strpool_p );
585 MAUG_MHANDLE out_h = (MAUG_MHANDLE)NULL;
587 char* out_tmp = NULL;
589 char* str_src = NULL;
591 if( !mdata_strpool_is_locked( sp ) ) {
592 mdata_strpool_lock( sp );
596 str_src = mdata_strpool_get( sp, idx );
597 if( NULL == str_src ) {
598 error_printf(
"invalid strpool index: " SSIZE_T_FMT, idx );
599 retval = MERROR_OVERFLOW;
603 str_sz = maug_strlen( str_src );
605 out_h = maug_malloc( str_sz + 1, 1 );
606 maug_cleanup_if_null_alloc( MAUG_MHANDLE, out_h );
608 maug_mlock( out_h, out_tmp );
609 maug_cleanup_if_null_lock(
char*, out_tmp );
611 maug_mzero( out_tmp, str_sz + 1 );
615 memcpy( out_tmp, str_src, str_sz );
619 if( NULL != out_tmp ) {
620 maug_munlock( out_h, out_tmp );
623 if( MERROR_OK != retval && (MAUG_MHANDLE)NULL != out_h ) {
628 mdata_strpool_unlock( sp );
636mdata_strpool_idx_t mdata_strpool_append(
637 struct MDATA_STRPOOL* strpool,
const char* str,
size_t str_sz, uint8_t flags
639 mdata_strpool_idx_t idx_p_out = 0;
640 char* strpool_p = NULL;
642 size_t* p_str_sz = NULL;
646 error_printf(
"attempted to add zero-length string!" );
647 retval = MERROR_OVERFLOW;
652 0 < strpool->str_sz &&
653 MDATA_STRPOOL_FLAG_DEDUPE == (MDATA_STRPOOL_FLAG_DEDUPE & flags)
657 idx_p_out = mdata_strpool_find( strpool, str, str_sz );
658 if( 0 < idx_p_out ) {
660#if MDATA_STRPOOL_TRACE_LVL > 0
661 debug_printf( MDATA_STRPOOL_TRACE_LVL,
662 "found duplicate string for add at index: " SSIZE_T_FMT,
670 alloc_sz =
sizeof( size_t ) + str_sz + 1 +
671 mdata_strpool_padding( str_sz );
672 assert( 0 == alloc_sz %
sizeof(
size_t ) );
674#if MDATA_STRPOOL_TRACE_LVL > 0
675 debug_printf( MDATA_STRPOOL_TRACE_LVL,
676 "adding size_t (" SIZE_T_FMT
" bytes) + string %s (" SIZE_T_FMT
677 " bytes) + 1 NULL + " SIZE_T_FMT
" bytes padding to strpool...",
678 sizeof(
size_t ), str, str_sz, mdata_strpool_padding( str_sz ) );
681 retval = mdata_strpool_alloc( strpool, alloc_sz );
682 maug_cleanup_if_not_ok();
684 maug_mlock( strpool->str_h, strpool_p );
685 maug_cleanup_if_null_alloc(
char*, strpool_p );
687#if MDATA_LOCK_TRACE_LVL > 0
688 debug_printf( MDATA_LOCK_TRACE_LVL,
689 "strpool (" SIZE_T_FMT
" bytes) locked to: %p",
690 strpool->str_sz, strpool_p );
695 &(strpool_p[strpool->str_sz +
sizeof(
size_t )]), str, str_sz );
696 strpool_p[strpool->str_sz +
sizeof( size_t ) + str_sz] =
'\0';
699 assert( 0 == strpool->str_sz %
sizeof(
size_t ) );
700 p_str_sz = (
size_t*)&(strpool_p[strpool->str_sz]);
701 *p_str_sz = alloc_sz;
703 idx_p_out = strpool->str_sz +
sizeof( size_t );
705#if MDATA_STRPOOL_TRACE_LVL > 0
706 debug_printf( MDATA_STRPOOL_TRACE_LVL,
707 "set strpool_idx: " SIZE_T_FMT
": \"%s\"",
708 strpool->str_sz, &(strpool_p[idx_p_out]) );
712 strpool->str_sz += alloc_sz;
716 if( MERROR_OK != retval ) {
720 if( NULL != strpool_p ) {
721 maug_munlock( strpool->str_h, strpool_p );
733 MAUG_MHANDLE str_h_new = (MAUG_MHANDLE)NULL;
735 if( (MAUG_MHANDLE)NULL == strpool->str_h ) {
736#if MDATA_STRPOOL_TRACE_LVL > 0
738 MDATA_STRPOOL_TRACE_LVL,
739 "creating string pool of " SIZE_T_FMT
" chars...",
742 assert( (MAUG_MHANDLE)NULL == strpool->str_h );
743 strpool->str_h = maug_malloc( alloc_sz, 1 );
744 maug_cleanup_if_null_alloc( MAUG_MHANDLE, strpool->str_h );
745 strpool->str_sz_max = alloc_sz;
747 }
else if( strpool->str_sz_max <= strpool->str_sz + alloc_sz ) {
748 while( strpool->str_sz_max <= strpool->str_sz + alloc_sz ) {
749#if MDATA_STRPOOL_TRACE_LVL > 0
751 MDATA_STRPOOL_TRACE_LVL,
752 "enlarging string pool to " SIZE_T_FMT
"...",
753 strpool->str_sz_max * 2 );
756 str_h_new, strpool->str_h, strpool->str_sz_max, (
size_t)2 );
757 strpool->str_sz_max *= 2;
768 if( (MAUG_MHANDLE)NULL != strpool->str_h ) {
769 maug_mfree( strpool->str_h );
775ssize_t mdata_vector_append(
776 struct MDATA_VECTOR* v,
const void* item,
size_t item_sz
779 ssize_t idx_out = -1;
782 error_printf(
"attempting to add item of " SIZE_T_FMT
" bytes to vector, "
783 "but vector is already sized for " SIZE_T_FMT
"-byte items!",
785 retval = MERROR_OVERFLOW;
792 mdata_vector_lock( v );
798#if MDATA_VECTOR_TRACE_LVL > 0
800 MDATA_VECTOR_TRACE_LVL,
"inserting into vector at index: " SIZE_T_FMT,
804 memcpy( _mdata_vector_item_ptr( v, idx_out ), item, item_sz );
811 if( MERROR_OK != retval ) {
812 error_printf(
"error adding to vector: %d", retval );
813 idx_out = retval * -1;
814 assert( 0 > idx_out );
817 mdata_vector_unlock( v );
824ssize_t mdata_vector_insert(
825 struct MDATA_VECTOR* v,
const void* item, ssize_t idx,
size_t item_sz
833 error_printf(
"attempting to add item of " SIZE_T_FMT
" bytes to vector, "
834 "but vector is already sized for " SIZE_T_FMT
"-byte items!",
836 retval = MERROR_OVERFLOW;
841 error_printf(
"attempting to insert beyond end of vector!" );
842 retval = MERROR_OVERFLOW;
849 mdata_vector_lock( v );
851 for( i = v->
ct ; idx < i ; i-- ) {
852#if MDATA_VECTOR_TRACE_LVL > 0
853 debug_printf( MDATA_VECTOR_TRACE_LVL,
854 "copying vector item " SSIZE_T_FMT
" to " SSIZE_T_FMT
"...",
858 _mdata_vector_item_ptr( v, i ),
859 _mdata_vector_item_ptr( v, i - 1),
863#if MDATA_VECTOR_TRACE_LVL > 0
865 MDATA_VECTOR_TRACE_LVL,
866 "inserting into vector at index: " SIZE_T_FMT, idx );
870 memcpy( _mdata_vector_item_ptr( v, idx ), item, item_sz );
873 maug_mzero( _mdata_vector_item_ptr( v, idx ), item_sz );
880 if( MERROR_OK != retval ) {
881 error_printf(
"error adding to vector: %d", retval );
886 mdata_vector_unlock( v );
897 if( mdata_vector_is_locked( v ) ) {
898 error_printf(
"vector cannot be resized while locked!" );
899 retval = MERROR_ALLOC;
904 error_printf(
"index out of range!" );
905 retval = MERROR_OVERFLOW;
909#if MDATA_VECTOR_TRACE_LVL > 0
910 debug_printf( MDATA_VECTOR_TRACE_LVL,
911 "removing vector item: " SIZE_T_FMT, idx );
916 mdata_vector_lock( v );
918 for( i = idx ; v->
ct > i + 1 ; i++ ) {
919#if MDATA_VECTOR_TRACE_LVL > 0
920 debug_printf( MDATA_VECTOR_TRACE_LVL,
921 "shifting " SIZE_T_FMT
"-byte vector item " SIZE_T_FMT
" up by 1...",
934 mdata_vector_unlock( v );
941void* mdata_vector_get_void(
const struct MDATA_VECTOR* v,
size_t idx ) {
943#if MDATA_VECTOR_TRACE_LVL > 0
944 debug_printf( MDATA_VECTOR_TRACE_LVL,
945 "getting vector item " SIZE_T_FMT
" (of " SIZE_T_FMT
")...",
954 return _mdata_vector_item_ptr( v, idx );
966 error_printf(
"vector cannot be copied while locked!" );
967 retval = MERROR_ALLOC;
972 assert( 0 < v_src->
ct_max );
975 v_dest->
ct = v_src->
ct;
977#if MDATA_VECTOR_TRACE_LVL > 0
978 debug_printf( MDATA_VECTOR_TRACE_LVL,
979 "copying " SIZE_T_FMT
" vector of " SIZE_T_FMT
"-byte nodes...",
982 assert( (MAUG_MHANDLE)NULL == v_dest->
data_h );
984 maug_cleanup_if_null_alloc( MAUG_MHANDLE, v_dest->
data_h );
986 mdata_vector_lock( v_dest );
987 mdata_vector_lock( v_src );
994 mdata_vector_unlock( v_src );
995 mdata_vector_unlock( v_dest );
1003 struct MDATA_VECTOR* v,
size_t item_sz,
size_t item_ct_init
1006 MAUG_MHANDLE data_h_new = (MAUG_MHANDLE)NULL;
1007 size_t new_ct = item_ct_init,
1008 new_bytes_start = 0,
1012 error_printf(
"vector cannot be resized while locked!" );
1013 retval = MERROR_ALLOC;
1018 if( (MAUG_MHANDLE)NULL == v->
data_h ) {
1019 assert( 0 == v->
ct_max );
1021 if( 0 < item_ct_init ) {
1022#if MDATA_VECTOR_TRACE_LVL > 0
1023 debug_printf( MDATA_VECTOR_TRACE_LVL,
"setting step sz: " SIZE_T_FMT,
1027 }
else if( 0 == v->
ct_step ) {
1028#if MDATA_VECTOR_TRACE_LVL > 0
1029 debug_printf( MDATA_VECTOR_TRACE_LVL,
"setting step sz: %d",
1030 MDATA_VECTOR_INIT_STEP_SZ );
1032 v->
ct_step = MDATA_VECTOR_INIT_STEP_SZ;
1035#if MDATA_VECTOR_TRACE_LVL > 0
1036 debug_printf( MDATA_VECTOR_TRACE_LVL,
1037 "creating " SIZE_T_FMT
" vector of " SIZE_T_FMT
"-byte nodes...",
1040 assert( (MAUG_MHANDLE)NULL == v->
data_h );
1042 assert( 0 < item_sz );
1044 maug_cleanup_if_null_alloc( MAUG_MHANDLE, v->
data_h );
1047 mdata_vector_lock( v );
1049 mdata_vector_unlock( v );
1051 }
else if( v->
ct_max <= v->
ct + 1 || v->
ct_max <= item_ct_init ) {
1052 assert( item_sz == v->
item_sz );
1055 if( item_ct_init < v->ct_max + v->
ct_step ) {
1061#if MDATA_VECTOR_TRACE_LVL > 0
1062 debug_printf( MDATA_VECTOR_TRACE_LVL,
1063 "enlarging vector to " SIZE_T_FMT
"...",
1066 maug_mrealloc_test( data_h_new, v->
data_h, new_ct, item_sz );
1070 assert( new_bytes_start >= v->
ct_max );
1071 new_bytes_sz = (new_ct * v->
item_sz) - new_bytes_start;
1072 assert( new_bytes_sz >= v->
item_sz );
1073 mdata_vector_lock( v );
1074 maug_mzero( &(v->
data_bytes[new_bytes_start]), new_bytes_sz );
1075 mdata_vector_unlock( v );
1098uint32_t mdata_hash(
const char* token,
size_t token_sz ) {
1099 uint32_t hash_out = 2166136261u;
1103 for( i = 0 ; token_sz > i ; i++ ) {
1107 if(
'A' <= c &&
'Z' >= c ) {
1112 hash_out *= 16777619u;
1123 mdata_vector_lock( &(t->data_cols[0]) );
1124 mdata_vector_lock( &(t->data_cols[1]) );
1142 mdata_vector_unlock( &(t->data_cols[0]) );
1143 mdata_vector_unlock( &(t->data_cols[1]) );
1145 if( MERROR_OK != retval ) {
1146 assert( mdata_vector_is_locked( &(t->data_cols[0]) ) );
1154struct MDATA_TABLE_REPLACE_CADDY {
1155 struct MDATA_TABLE_KEY* key;
1161ssize_t _mdata_table_hunt_index(
1163 const char* key, uint32_t key_hash,
size_t key_sz
1168 if( 0 == mdata_table_ct( t ) ) {
1172 assert( mdata_vector_is_locked( &(t->data_cols[0]) ) );
1176 key_sz = maug_strlen( key );
1177 if( MDATA_TABLE_KEY_SZ_MAX < key_sz ) {
1178 key_sz = MDATA_TABLE_KEY_SZ_MAX;
1180 key_hash = mdata_hash( key, key_sz );
1182#if MDATA_TABLE_TRACE_LVL > 0
1183 debug_printf( MDATA_TABLE_TRACE_LVL,
1184 "searching for key: %s (%u)", key, key_hash );
1190 for( i = 0 ; mdata_vector_ct( &(t->data_cols[0]) ) > i ; i++ ) {
1191 key_iter = mdata_vector_get(
1193 assert( NULL != key );
1195 key_iter->hash == key_hash &&
1196 key_iter->string_sz == key_sz
1198#if MDATA_TABLE_TRACE_LVL > 0
1199 debug_printf( MDATA_TABLE_TRACE_LVL,
"found value for key: %s", key );
1214 void* cb_data,
size_t cb_data_sz,
size_t idx
1217 struct MDATA_TABLE_REPLACE_CADDY* caddy =
1218 (
struct MDATA_TABLE_REPLACE_CADDY*)cb_data;
1221 key->hash == caddy->key->hash && key->string_sz == caddy->key->string_sz
1223#if MDATA_TABLE_TRACE_LVL > 0
1224 debug_printf( MDATA_TABLE_TRACE_LVL,
1225 "replacing table data for key %s (%u)...", key->string, key->hash );
1227 memcpy( data, caddy->data, data_sz );
1228 retval = MERROR_FILE;
1238 mdata_table_iter_t cb,
void* cb_data,
size_t cb_data_sz
1244 char* p_value = NULL;
1246 if( 0 == mdata_table_ct( t ) ) {
1250 if( !mdata_table_is_locked( t ) ) {
1251#if MDATA_LOCK_TRACE_LVL > 0
1252 debug_printf( MDATA_LOCK_TRACE_LVL,
"engaging table autolock..." );
1254 mdata_table_lock( t );
1259 for( i = 0 ; mdata_table_ct( t ) > i ; i++ ) {
1260 p_key = mdata_vector_get_void( &(t->data_cols[0]), i );
1261 assert( NULL != p_key );
1262 assert( 0 < p_key->string_sz );
1263 assert( p_key->string_sz == maug_strlen( p_key->string ) );
1264 p_value = mdata_vector_get_void( &(t->data_cols[1]), i );
1266 p_key, p_value, t->data_cols[1].
item_sz, cb_data, cb_data_sz, i );
1267 maug_cleanup_if_not_ok();
1273 mdata_table_unlock( t );
1283 void* value,
size_t value_sz
1286 ssize_t idx_key = -1;
1287 ssize_t idx_val = -1;
1289 struct MDATA_TABLE_REPLACE_CADDY caddy;
1291 assert( 0 < maug_strlen( key ) );
1293 assert( !mdata_table_is_locked( t ) );
1296 mdata_vector_ct( &(t->data_cols[0]) ) ==
1297 mdata_vector_ct( &(t->data_cols[1]) ) );
1301 maug_strncpy( key_tmp.string, key, MDATA_TABLE_KEY_SZ_MAX );
1302 if( maug_strlen( key ) > MDATA_TABLE_KEY_SZ_MAX + 1 ) {
1304 "key %s is longer than maximum key size! truncating to: %s",
1305 key, key_tmp.string );
1307 key_tmp.string_sz = strlen( key_tmp.string );
1308 key_tmp.hash = mdata_hash( key_tmp.string, key_tmp.string_sz );
1310#if MDATA_TABLE_TRACE_LVL > 0
1311 debug_printf( MDATA_TABLE_TRACE_LVL,
1312 "attempting to set key %s (%u) to " SIZE_T_FMT
"-byte value...",
1313 key_tmp.string, key_tmp.hash, value_sz );
1316 caddy.key = &key_tmp;
1321 retval = mdata_table_iter( t, _mdata_table_replace, &caddy,
1322 sizeof(
struct MDATA_TABLE_REPLACE_CADDY ) );
1323 if( MERROR_FILE == retval ) {
1331 idx_key = mdata_vector_append(
1334 error_printf(
"error appending table key: %d", idx_key );
1335 retval = merror_sz_to_retval( idx_key );
1340 idx_val = mdata_vector_append( &(t->data_cols[1]), value, value_sz );
1341 assert( 0 <= idx_val );
1343 error_printf(
"error appending table value: %d", idx_val );
1344 retval = merror_sz_to_retval( idx_val );
1363#if MDATA_TABLE_TRACE_LVL > 0
1364 debug_printf( MDATA_TABLE_TRACE_LVL,
"unsetting table key: %s", key );
1370 if( !mdata_table_is_locked( t ) ) {
1371#if MDATA_LOCK_TRACE_LVL > 0
1372 debug_printf( MDATA_LOCK_TRACE_LVL,
"autolocking table vectors" );
1374 assert( !mdata_vector_is_locked( &(t->data_cols[0]) ) );
1375 assert( !mdata_vector_is_locked( &(t->data_cols[1]) ) );
1376 mdata_table_lock( t );
1380 idx = _mdata_table_hunt_index( t, key, 0, 0 );
1386 mdata_table_unlock( t );
1387 mdata_vector_remove( &(t->data_cols[0]), idx );
1388 mdata_vector_remove( &(t->data_cols[1]), idx );
1392 if( autolock && mdata_table_is_locked( t ) ) {
1393 mdata_table_unlock( t );
1394 }
else if( !autolock && !mdata_table_is_locked( t ) ) {
1395 mdata_table_lock( t );
1403void* mdata_table_get_void(
const struct MDATA_TABLE* t,
const char* key ) {
1405 void* value_out = NULL;
1408 assert( mdata_table_is_locked( t ) );
1410 idx = _mdata_table_hunt_index( t, key, 0, 0 );
1412 retval = MERROR_OVERFLOW;
1416 value_out = mdata_vector_get_void( &(t->data_cols[1]), idx );
1420 if( MERROR_OK != retval ) {
1429void* mdata_table_hash_get_void(
1430 struct MDATA_TABLE* t, uint32_t key_hash,
size_t key_sz
1433 void* value_out = NULL;
1436 assert( mdata_table_is_locked( t ) );
1438#if MDATA_TABLE_TRACE_LVL > 0
1439 debug_printf( MDATA_TABLE_TRACE_LVL,
1440 "searching for hash %u (" SIZE_T_FMT
")", key_hash, key_sz );
1443 idx = _mdata_table_hunt_index( t, NULL, key_hash, key_sz );
1445 retval = MERROR_OVERFLOW;
1449 value_out = mdata_vector_get_void( &(t->data_cols[1]), idx );
1453 if( MERROR_OK != retval ) {
1463 mdata_vector_free( &(t->data_cols[0]) );
1464 mdata_vector_free( &(t->data_cols[1]) );
uint16_t MERROR_RETVAL
Return type indicating function returns a value from this list.
Definition merror.h:28
MAUG_MHANDLE mdata_strpool_extract(struct MDATA_STRPOOL *sp, mdata_strpool_idx_t idx)
Return a dynamically-allocated memory handle containing the contents of the string at the given index...
MERROR_RETVAL mdata_strpool_check_idx(struct MDATA_STRPOOL *sp, mdata_strpool_idx_t idx)
Verify if the given mdata_strpool_idx_t is valid in the given strpool.
ssize_t mdata_vector_append(struct MDATA_VECTOR *v, const void *item, size_t item_sz)
Append an item to the specified vector.
MERROR_RETVAL mdata_vector_remove(struct MDATA_VECTOR *v, size_t idx)
Remove item at the given index, shifting subsequent items up by 1.
void * mdata_vector_get_void(const struct MDATA_VECTOR *v, size_t idx)
Get a generic pointer to an item in the MDATA_VECTOR.
MERROR_RETVAL mdata_vector_alloc(struct MDATA_VECTOR *v, size_t item_sz, size_t item_ct_init)
A pool of immutable text strings. Deduplicates strings to save memory.
Definition mdata.h:80
A vector of uniformly-sized objects, stored contiguously.
Definition mdata.h:105
size_t ct_step
Number of items added when more space is needed.
Definition mdata.h:116
MAUG_MHANDLE data_h
Handle for allocated items (unlocked).
Definition mdata.h:108
size_t item_sz
Size, in bytes, of each item.
Definition mdata.h:121
size_t ct
Maximum number of items actually used.
Definition mdata.h:114
uint8_t * data_bytes
Handle for allocated items (locked).
Definition mdata.h:110
size_t ct_max
Maximum number of items currently allocated for.
Definition mdata.h:112
ssize_t locks
Lock count, if MDATA_VECTOR_FLAG_REFCOUNT is enabled.
Definition mdata.h:123