13#ifndef MDATA_TRACE_LVL
14# define MDATA_TRACE_LVL 0
17#ifndef MDATA_TABLE_KEY_SZ_MAX
18# define MDATA_TABLE_KEY_SZ_MAX 8
34#define MDATA_VECTOR_FLAG_REFCOUNT 0x01
36#define MDATA_VECTOR_FLAG_IS_LOCKED 0x02
38#ifndef MDATA_VECTOR_INIT_STEP_SZ
43# define MDATA_VECTOR_INIT_STEP_SZ 10
55#define MDATA_STRPOOL_FLAG_IS_LOCKED 0x01
57#define MDATA_STRPOOL_FLAG_DEDUPE 0x02
59typedef size_t mdata_strpool_idx_t;
122 char string[MDATA_TABLE_KEY_SZ_MAX + 1];
128 volatile uint16_t flags;
146mdata_strpool_idx_t mdata_strpool_find(
156mdata_strpool_idx_t mdata_strpool_append(
157 struct MDATA_STRPOOL* sp,
const char* str,
size_t str_sz, uint8_t flags );
190ssize_t mdata_vector_insert(
224uint32_t mdata_hash(
const char* token,
size_t token_sz );
233 void* cb_data,
size_t cb_data_sz,
size_t idx );
241 mdata_table_iter_t cb,
void* cb_data,
size_t cb_data_sz );
245 void* value,
size_t value_sz );
250void* mdata_table_get_void(
const struct MDATA_TABLE* t,
const char* key );
252void* mdata_table_hash_get_void(
253 struct MDATA_TABLE* t, uint32_t key_hash,
size_t key_sz );
259#if MDATA_TRACE_LVL > 0
260# define mdata_debug_printf( fmt, ... ) \
261 debug_printf( MDATA_TRACE_LVL, fmt, __VA_ARGS__ );
263# define mdata_debug_printf( fmt, ... )
271#define mdata_strpool_sz( sp ) ((sp)->str_sz_max)
273#define mdata_strpool_is_locked( sp ) \
274 (MDATA_STRPOOL_FLAG_IS_LOCKED == \
275 (MDATA_STRPOOL_FLAG_IS_LOCKED & (sp)->flags))
277#define mdata_strpool_lock( sp ) \
278 mdata_debug_printf( "locking strpool %p...", sp ); \
279 if( NULL != (sp)->str_p ) { \
280 error_printf( "str_p not null! double lock?" ); \
281 retval = MERROR_ALLOC; \
284 maug_mlock( (sp)->str_h, (sp)->str_p ); \
285 maug_cleanup_if_null_lock( char*, (sp)->str_p ); \
286 (sp)->flags |= MDATA_STRPOOL_FLAG_IS_LOCKED;
288#define mdata_strpool_unlock( sp ) \
289 mdata_debug_printf( "unlocking strpool %p...", sp ); \
290 if( NULL != (sp)->str_p ) { \
291 maug_munlock( (sp)->str_h, (sp)->str_p ); \
292 (sp)->flags &= ~MDATA_STRPOOL_FLAG_IS_LOCKED; \
295#define mdata_strpool_get( sp, idx ) \
296 ((idx >= 1 && idx < (sp)->str_sz) ? &((sp)->str_p[idx]) : NULL)
298#define mdata_strpool_get_sz( sp, idx ) \
299 ((idx >= sizeof( size_t ) && idx < (sp)->str_sz) ? \
300 (size_t)(*(&((sp)->str_p[idx - sizeof( size_t )]))) : 0)
302#define mdata_strpool_padding( str_sz ) \
303 (sizeof( size_t ) - ((str_sz + 1 ) % sizeof( size_t )))
320#define mdata_vector_lock( v ) \
321 if( (MAUG_MHANDLE)NULL == (v)->data_h && NULL == (v)->data_bytes ) { \
322 mdata_debug_printf( "locking empty vector..." ); \
323 (v)->flags |= MDATA_VECTOR_FLAG_IS_LOCKED; \
325 mdata_vector_get_flag( v, MDATA_VECTOR_FLAG_REFCOUNT ) && \
329 mdata_debug_printf( "vector " #v " locks: " SSIZE_T_FMT, (v)->locks ); \
332 if( mdata_vector_is_locked( v ) ) { \
333 error_printf( "attempting to double-lock vector!" ); \
334 retval = MERROR_OVERFLOW; \
337 if( (MAUG_MHANDLE)NULL == (v)->data_h ) { \
338 error_printf( "invalid data handle!" ); \
339 retval = MERROR_ALLOC; \
342 maug_mlock( (v)->data_h, (v)->data_bytes ); \
343 maug_cleanup_if_null_lock( uint8_t*, (v)->data_bytes ); \
344 (v)->flags |= MDATA_VECTOR_FLAG_IS_LOCKED; \
345 mdata_debug_printf( "locked vector " #v ); \
353#define mdata_vector_unlock( v ) \
354 if( (MAUG_MHANDLE)NULL == (v)->data_h && NULL == (v)->data_bytes ) { \
355 mdata_debug_printf( "locking empty vector..." ); \
356 (v)->flags &= ~MDATA_VECTOR_FLAG_IS_LOCKED; \
359 mdata_vector_get_flag( v, MDATA_VECTOR_FLAG_REFCOUNT ) && \
363 mdata_debug_printf( "vector " #v " locks: " SSIZE_T_FMT, \
366 if( 0 == (v)->locks && NULL != (v)->data_bytes ) { \
367 assert( mdata_vector_is_locked( v ) ); \
368 maug_munlock( (v)->data_h, (v)->data_bytes ); \
369 (v)->flags &= ~MDATA_VECTOR_FLAG_IS_LOCKED; \
370 mdata_debug_printf( "unlocked vector " #v ); \
374#define mdata_vector_get( v, idx, type ) \
375 ((type*)mdata_vector_get_void( v, idx ))
377#define mdata_vector_get_last( v, type ) \
378 (0 < mdata_vector_ct( v ) ? \
379 ((type*)mdata_vector_get_void( v, \
380 mdata_vector_ct( v ) - 1 )) : NULL)
382#define mdata_vector_remove_last( v ) \
383 (0 < mdata_vector_ct( v ) ? \
384 (mdata_vector_remove( v, mdata_vector_ct( v ) - 1 )) : MERROR_OVERFLOW)
386#define mdata_vector_set_ct_step( v, step ) \
396#define mdata_vector_ct( v ) ((v)->ct)
402#define mdata_vector_sz( v ) (((v)->ct_max) * ((v)->item_sz))
408#define mdata_vector_fill( v, ct_new, sz ) \
409 retval = mdata_vector_alloc( v, sz, ct_new ); \
410 maug_cleanup_if_not_ok(); \
413#define mdata_vector_is_locked( v ) \
414 (MDATA_VECTOR_FLAG_IS_LOCKED == \
415 (MDATA_VECTOR_FLAG_IS_LOCKED & (v)->flags))
418#define mdata_vector_insert_sort( v, i, t, field )
421#define mdata_vector_sort( v, t, field )
423#define _mdata_vector_item_ptr( v, idx ) \
424 (&((v)->data_bytes[((idx) * ((v)->item_sz))]))
426#define mdata_vector_set_flag( v, flag ) (v)->flags |= (flag)
428#define mdata_vector_get_flag( v, flag ) ((flag) == ((v)->flags & (flag)))
437#define mdata_table_is_locked( t ) \
438 (mdata_vector_is_locked( &((t)->data_cols[0]) ))
440#define mdata_table_get( t, key, type ) \
441 ((type*)mdata_table_get_void( t, key ))
443#define mdata_table_hash_get( t, hash, sz, type ) \
444 ((type*)mdata_table_hash_get_void( t, hash, sz ))
446#define mdata_table_ct( t ) ((t)->data_cols[0].ct)
448#define mdata_table_sz( t ) \
449 mdata_vector_sz( &((t)->data_cols[0]) ) + \
450 mdata_vector_sz( &((t)->data_cols[1]) )
454#define mdata_retval( idx ) (0 > idx ? ((idx) * -1) : MERROR_OK)
462 mdata_strpool_idx_t i = 0;
465 if( !mdata_strpool_is_locked( sp ) ) {
466 mdata_strpool_lock( sp );
470 for( i = 0 ; sp->str_sz > i ; i += (size_t)*(&(sp->str_p[i])) ) {
480 mdata_strpool_unlock( sp );
490 char* strpool_p = NULL;
492 maug_mlock( sp->str_h, strpool_p );
494 for( i = 0 ; mdata_strpool_sz( sp ) > i ; i++ ) {
495 printf(
"0x%02x ", strpool_p[i] );
499 if( NULL != strpool_p ) {
500 maug_munlock( sp->str_h, strpool_p );
506mdata_strpool_idx_t mdata_strpool_find(
507 struct MDATA_STRPOOL* strpool,
const char* str,
size_t str_sz
510 mdata_strpool_idx_t i = 0;
511 char* strpool_p = NULL;
512 size_t* p_str_iter_sz = NULL;
514 if( (MAUG_MHANDLE)NULL == strpool->str_h ) {
515 error_printf(
"strpool not allocated!" );
520 maug_mlock( strpool->str_h, strpool_p );
522 while( i < strpool->str_sz ) {
523 p_str_iter_sz = (
size_t*)&(strpool_p[i]);
525 0 == strncmp( &(strpool_p[i +
sizeof(
size_t )]), str, str_sz + 1 )
528 i +=
sizeof( size_t );
529#if MDATA_TRACE_LVL > 0
530 debug_printf( MDATA_TRACE_LVL,
531 "found strpool_idx: " SIZE_T_FMT
" (" SIZE_T_FMT
" bytes): \"%s\"",
532 i, *p_str_iter_sz, &(strpool_p[i]) );
536#if MDATA_TRACE_LVL > 0
538 debug_printf( MDATA_TRACE_LVL,
539 "skipping strpool_idx: " SIZE_T_FMT
" (" SIZE_T_FMT
541 i +
sizeof(
size_t ), *p_str_iter_sz,
542 &(strpool_p[i +
sizeof(
size_t )]) );
553 if( MERROR_OK != retval ) {
557 if( NULL != strpool_p ) {
558 maug_munlock( strpool->str_h, strpool_p );
570 MAUG_MHANDLE out_h = (MAUG_MHANDLE)NULL;
572 char* out_tmp = NULL;
574 char* str_src = NULL;
576 if( !mdata_strpool_is_locked( sp ) ) {
577 mdata_strpool_lock( sp );
581 str_src = mdata_strpool_get( sp, idx );
582 if( NULL == str_src ) {
583 error_printf(
"invalid strpool index: " SSIZE_T_FMT, idx );
584 retval = MERROR_OVERFLOW;
588 str_sz = maug_strlen( str_src );
590 out_h = maug_malloc( str_sz + 1, 1 );
591 maug_cleanup_if_null_alloc( MAUG_MHANDLE, out_h );
593 maug_mlock( out_h, out_tmp );
594 maug_cleanup_if_null_lock(
char*, out_tmp );
596 maug_mzero( out_tmp, str_sz + 1 );
600 memcpy( out_tmp, str_src, str_sz );
604 if( NULL != out_tmp ) {
605 maug_munlock( out_h, out_tmp );
608 if( MERROR_OK != retval && (MAUG_MHANDLE)NULL != out_h ) {
613 mdata_strpool_unlock( sp );
621mdata_strpool_idx_t mdata_strpool_append(
622 struct MDATA_STRPOOL* strpool,
const char* str,
size_t str_sz, uint8_t flags
624 mdata_strpool_idx_t idx_p_out = 0;
625 char* strpool_p = NULL;
627 size_t* p_str_sz = NULL;
631 error_printf(
"attempted to add zero-length string!" );
632 retval = MERROR_OVERFLOW;
637 0 < strpool->str_sz &&
638 MDATA_STRPOOL_FLAG_DEDUPE == (MDATA_STRPOOL_FLAG_DEDUPE & flags)
642 idx_p_out = mdata_strpool_find( strpool, str, str_sz );
643 if( 0 < idx_p_out ) {
645#if MDATA_TRACE_LVL > 0
646 debug_printf( MDATA_TRACE_LVL,
647 "found duplicate string for add at index: " SSIZE_T_FMT,
655 alloc_sz =
sizeof( size_t ) + str_sz + 1 +
656 mdata_strpool_padding( str_sz );
657 assert( 0 == alloc_sz %
sizeof(
size_t ) );
659#if MDATA_TRACE_LVL > 0
660 debug_printf( MDATA_TRACE_LVL,
661 "adding size_t (" SIZE_T_FMT
" bytes) + string %s (" SIZE_T_FMT
662 " bytes) + 1 NULL + " SIZE_T_FMT
" bytes padding to strpool...",
663 sizeof(
size_t ), str, str_sz, mdata_strpool_padding( str_sz ) );
666 retval = mdata_strpool_alloc( strpool, alloc_sz );
667 maug_cleanup_if_not_ok();
669 maug_mlock( strpool->str_h, strpool_p );
670 maug_cleanup_if_null_alloc(
char*, strpool_p );
672#if MDATA_TRACE_LVL > 0
673 debug_printf( MDATA_TRACE_LVL,
674 "strpool (" SIZE_T_FMT
" bytes) locked to: %p",
675 strpool->str_sz, strpool_p );
680 &(strpool_p[strpool->str_sz +
sizeof(
size_t )]), str, str_sz );
681 strpool_p[strpool->str_sz +
sizeof( size_t ) + str_sz] =
'\0';
684 assert( 0 == strpool->str_sz %
sizeof(
size_t ) );
685 p_str_sz = (
size_t*)&(strpool_p[strpool->str_sz]);
686 *p_str_sz = alloc_sz;
688 idx_p_out = strpool->str_sz +
sizeof( size_t );
690#if MDATA_TRACE_LVL > 0
691 debug_printf( MDATA_TRACE_LVL,
"set strpool_idx: " SIZE_T_FMT
": \"%s\"",
692 strpool->str_sz, &(strpool_p[idx_p_out]) );
696 strpool->str_sz += alloc_sz;
700 if( MERROR_OK != retval ) {
704 if( NULL != strpool_p ) {
705 maug_munlock( strpool->str_h, strpool_p );
717 MAUG_MHANDLE str_h_new = (MAUG_MHANDLE)NULL;
719 if( (MAUG_MHANDLE)NULL == strpool->str_h ) {
720#if MDATA_TRACE_LVL > 0
722 MDATA_TRACE_LVL,
"creating string pool of " SIZE_T_FMT
" chars...",
725 assert( (MAUG_MHANDLE)NULL == strpool->str_h );
726 strpool->str_h = maug_malloc( alloc_sz, 1 );
727 maug_cleanup_if_null_alloc( MAUG_MHANDLE, strpool->str_h );
728 strpool->str_sz_max = alloc_sz;
730 }
else if( strpool->str_sz_max <= strpool->str_sz + alloc_sz ) {
731 while( strpool->str_sz_max <= strpool->str_sz + alloc_sz ) {
732#if MDATA_TRACE_LVL > 0
734 MDATA_TRACE_LVL,
"enlarging string pool to " SIZE_T_FMT
"...",
735 strpool->str_sz_max * 2 );
738 str_h_new, strpool->str_h, strpool->str_sz_max, (
size_t)2 );
739 strpool->str_sz_max *= 2;
750 if( (MAUG_MHANDLE)NULL != strpool->str_h ) {
751 maug_mfree( strpool->str_h );
757ssize_t mdata_vector_append(
758 struct MDATA_VECTOR* v,
const void* item,
size_t item_sz
761 ssize_t idx_out = -1;
764 error_printf(
"attempting to add item of " SIZE_T_FMT
" bytes to vector, "
765 "but vector is already sized for " SIZE_T_FMT
"-byte items!",
767 retval = MERROR_OVERFLOW;
774 mdata_vector_lock( v );
780#if MDATA_TRACE_LVL > 0
782 MDATA_TRACE_LVL,
"inserting into vector at index: " SIZE_T_FMT,
786 memcpy( _mdata_vector_item_ptr( v, idx_out ), item, item_sz );
793 if( MERROR_OK != retval ) {
794 error_printf(
"error adding to vector: %d", retval );
795 idx_out = retval * -1;
796 assert( 0 > idx_out );
799 mdata_vector_unlock( v );
806ssize_t mdata_vector_insert(
807 struct MDATA_VECTOR* v,
const void* item, ssize_t idx,
size_t item_sz
815 error_printf(
"attempting to add item of " SIZE_T_FMT
" bytes to vector, "
816 "but vector is already sized for " SIZE_T_FMT
"-byte items!",
818 retval = MERROR_OVERFLOW;
823 error_printf(
"attempting to insert beyond end of vector!" );
824 retval = MERROR_OVERFLOW;
831 mdata_vector_lock( v );
833 for( i = v->
ct ; idx < i ; i-- ) {
834#if MDATA_TRACE_LVL > 0
835 debug_printf( MDATA_TRACE_LVL,
836 "copying vector item " SSIZE_T_FMT
" to " SSIZE_T_FMT
"...",
840 _mdata_vector_item_ptr( v, i ),
841 _mdata_vector_item_ptr( v, i - 1),
845#if MDATA_TRACE_LVL > 0
847 MDATA_TRACE_LVL,
"inserting into vector at index: " SIZE_T_FMT, idx );
851 memcpy( _mdata_vector_item_ptr( v, idx ), item, item_sz );
854 maug_mzero( _mdata_vector_item_ptr( v, idx ), item_sz );
861 if( MERROR_OK != retval ) {
862 error_printf(
"error adding to vector: %d", retval );
867 mdata_vector_unlock( v );
878 if( mdata_vector_is_locked( v ) ) {
879 error_printf(
"vector cannot be resized while locked!" );
880 retval = MERROR_ALLOC;
885 error_printf(
"index out of range!" );
886 retval = MERROR_OVERFLOW;
890#if MDATA_TRACE_LVL > 0
891 debug_printf( MDATA_TRACE_LVL,
"removing vector item: " SIZE_T_FMT, idx );
896 mdata_vector_lock( v );
898 for( i = idx ; v->
ct > i + 1 ; i++ ) {
899#if MDATA_TRACE_LVL > 0
900 debug_printf( MDATA_TRACE_LVL,
901 "shifting " SIZE_T_FMT
"-byte vector item " SIZE_T_FMT
" up by 1...",
914 mdata_vector_unlock( v );
921void* mdata_vector_get_void(
const struct MDATA_VECTOR* v,
size_t idx ) {
923#if MDATA_TRACE_LVL > 0
924 debug_printf( MDATA_TRACE_LVL,
925 "getting vector item " SIZE_T_FMT
" (of " SIZE_T_FMT
")...",
934 return _mdata_vector_item_ptr( v, idx );
946 error_printf(
"vector cannot be copied while locked!" );
947 retval = MERROR_ALLOC;
952 assert( 0 < v_src->
ct_max );
955 v_dest->
ct = v_src->
ct;
957#if MDATA_TRACE_LVL > 0
958 debug_printf( MDATA_TRACE_LVL,
959 "copying " SIZE_T_FMT
" vector of " SIZE_T_FMT
"-byte nodes...",
962 assert( (MAUG_MHANDLE)NULL == v_dest->
data_h );
964 maug_cleanup_if_null_alloc( MAUG_MHANDLE, v_dest->
data_h );
966 mdata_vector_lock( v_dest );
967 mdata_vector_lock( v_src );
974 mdata_vector_unlock( v_src );
975 mdata_vector_unlock( v_dest );
983 struct MDATA_VECTOR* v,
size_t item_sz,
size_t item_ct_init
986 MAUG_MHANDLE data_h_new = (MAUG_MHANDLE)NULL;
987 size_t new_ct = item_ct_init,
992 error_printf(
"vector cannot be resized while locked!" );
993 retval = MERROR_ALLOC;
998 if( (MAUG_MHANDLE)NULL == v->
data_h ) {
1001 if( 0 < item_ct_init ) {
1002#if MDATA_TRACE_LVL > 0
1003 debug_printf( MDATA_TRACE_LVL,
"setting step sz: " SIZE_T_FMT,
1007 }
else if( 0 == v->
ct_step ) {
1008#if MDATA_TRACE_LVL > 0
1009 debug_printf( MDATA_TRACE_LVL,
"setting step sz: %d",
1010 MDATA_VECTOR_INIT_STEP_SZ );
1012 v->
ct_step = MDATA_VECTOR_INIT_STEP_SZ;
1015#if MDATA_TRACE_LVL > 0
1016 debug_printf( MDATA_TRACE_LVL,
1017 "creating " SIZE_T_FMT
" vector of " SIZE_T_FMT
"-byte nodes...",
1020 assert( (MAUG_MHANDLE)NULL == v->
data_h );
1022 assert( 0 < item_sz );
1024 maug_cleanup_if_null_alloc( MAUG_MHANDLE, v->
data_h );
1027 mdata_vector_lock( v );
1029 mdata_vector_unlock( v );
1031 }
else if( v->
ct_max <= v->
ct + 1 || v->
ct_max <= item_ct_init ) {
1032 assert( item_sz == v->
item_sz );
1035 if( item_ct_init < v->ct_max + v->
ct_step ) {
1041#if MDATA_TRACE_LVL > 0
1042 debug_printf( MDATA_TRACE_LVL,
"enlarging vector to " SIZE_T_FMT
"...",
1045 maug_mrealloc_test( data_h_new, v->
data_h, new_ct, item_sz );
1049 assert( new_bytes_start >= v->
ct_max );
1050 new_bytes_sz = (new_ct * v->
item_sz) - new_bytes_start;
1051 assert( new_bytes_sz >= v->
item_sz );
1052 mdata_vector_lock( v );
1053 maug_mzero( &(v->
data_bytes[new_bytes_start]), new_bytes_sz );
1054 mdata_vector_unlock( v );
1077uint32_t mdata_hash(
const char* token,
size_t token_sz ) {
1078 uint32_t hash_out = 2166136261u;
1082 for( i = 0 ; token_sz > i ; i++ ) {
1086 if(
'A' <= c &&
'Z' >= c ) {
1091 hash_out *= 16777619u;
1102 mdata_vector_lock( &(t->data_cols[0]) );
1103 mdata_vector_lock( &(t->data_cols[1]) );
1121 mdata_vector_unlock( &(t->data_cols[0]) );
1122 mdata_vector_unlock( &(t->data_cols[1]) );
1124 if( MERROR_OK != retval ) {
1125 assert( mdata_vector_is_locked( &(t->data_cols[0]) ) );
1133struct MDATA_TABLE_REPLACE_CADDY {
1134 struct MDATA_TABLE_KEY* key;
1140ssize_t _mdata_table_hunt_index(
1142 const char* key, uint32_t key_hash,
size_t key_sz
1147 if( 0 == mdata_table_ct( t ) ) {
1151 assert( mdata_vector_is_locked( &(t->data_cols[0]) ) );
1155 key_sz = maug_strlen( key );
1156 if( MDATA_TABLE_KEY_SZ_MAX < key_sz ) {
1157 key_sz = MDATA_TABLE_KEY_SZ_MAX;
1159 key_hash = mdata_hash( key, key_sz );
1164 for( i = 0 ; mdata_vector_ct( &(t->data_cols[0]) ) > i ; i++ ) {
1165 key_iter = mdata_vector_get(
1167 assert( NULL != key );
1169 key_iter->hash == key_hash &&
1170 key_iter->string_sz == key_sz
1172#if MDATA_TRACE_LVL > 0
1173 debug_printf( MDATA_TRACE_LVL,
"found value for key: %s", key );
1188 void* cb_data,
size_t cb_data_sz,
size_t idx
1191 struct MDATA_TABLE_REPLACE_CADDY* caddy =
1192 (
struct MDATA_TABLE_REPLACE_CADDY*)cb_data;
1195 key->hash == caddy->key->hash && key->string_sz == caddy->key->string_sz
1197#if MDATA_TRACE_LVL > 0
1198 debug_printf( MDATA_TRACE_LVL,
1199 "replacing table data for key %s (%u)...", key->string, key->hash );
1201 memcpy( data, caddy->data, data_sz );
1202 retval = MERROR_FILE;
1212 mdata_table_iter_t cb,
void* cb_data,
size_t cb_data_sz
1218 char* p_value = NULL;
1220 if( 0 == mdata_table_ct( t ) ) {
1224 if( !mdata_table_is_locked( t ) ) {
1225#if MDATA_TRACE_LVL > 0
1226 debug_printf( MDATA_TRACE_LVL,
"engaging table autolock..." );
1228 mdata_table_lock( t );
1233 for( i = 0 ; mdata_table_ct( t ) > i ; i++ ) {
1234 p_key = mdata_vector_get_void( &(t->data_cols[0]), i );
1235 assert( NULL != p_key );
1236 assert( 0 < p_key->string_sz );
1237 assert( p_key->string_sz == maug_strlen( p_key->string ) );
1238 p_value = mdata_vector_get_void( &(t->data_cols[1]), i );
1240 p_key, p_value, t->data_cols[1].
item_sz, cb_data, cb_data_sz, i );
1241 maug_cleanup_if_not_ok();
1247 mdata_table_unlock( t );
1257 void* value,
size_t value_sz
1260 ssize_t idx_key = -1;
1261 ssize_t idx_val = -1;
1263 struct MDATA_TABLE_REPLACE_CADDY caddy;
1265 assert( 0 < maug_strlen( key ) );
1267 assert( !mdata_table_is_locked( t ) );
1270 mdata_vector_ct( &(t->data_cols[0]) ) ==
1271 mdata_vector_ct( &(t->data_cols[1]) ) );
1275 maug_strncpy( key_tmp.string, key, MDATA_TABLE_KEY_SZ_MAX );
1276 if( maug_strlen( key ) > MDATA_TABLE_KEY_SZ_MAX + 1 ) {
1278 "key %s is longer than maximum key size! truncating to: %s",
1279 key, key_tmp.string );
1281 key_tmp.string_sz = strlen( key_tmp.string );
1282 key_tmp.hash = mdata_hash( key_tmp.string, key_tmp.string_sz );
1284#if MDATA_TRACE_LVL > 0
1285 debug_printf( MDATA_TRACE_LVL,
1286 "attempting to set key %s (%u) to " SIZE_T_FMT
"-byte value...",
1287 key_tmp.string, key_tmp.hash, value_sz );
1290 caddy.key = &key_tmp;
1295 retval = mdata_table_iter( t, _mdata_table_replace, &caddy,
1296 sizeof(
struct MDATA_TABLE_REPLACE_CADDY ) );
1297 if( MERROR_FILE == retval ) {
1305 idx_key = mdata_vector_append(
1307 assert( 0 <= idx_key );
1311 idx_val = mdata_vector_append( &(t->data_cols[1]), value, value_sz );
1312 assert( 0 <= idx_val );
1330#if MDATA_TRACE_LVL > 0
1331 debug_printf( MDATA_TRACE_LVL,
"unsetting table key: %s", key );
1337 if( !mdata_table_is_locked( t ) ) {
1338#if MDATA_TRACE_LVL > 0
1339 debug_printf( MDATA_TRACE_LVL,
"autolocking table vectors" );
1341 assert( !mdata_vector_is_locked( &(t->data_cols[0]) ) );
1342 assert( !mdata_vector_is_locked( &(t->data_cols[1]) ) );
1343 mdata_table_lock( t );
1347 idx = _mdata_table_hunt_index( t, key, 0, 0 );
1353 mdata_table_unlock( t );
1354 mdata_vector_remove( &(t->data_cols[0]), idx );
1355 mdata_vector_remove( &(t->data_cols[1]), idx );
1359 if( autolock && mdata_table_is_locked( t ) ) {
1360 mdata_table_unlock( t );
1361 }
else if( !autolock && !mdata_table_is_locked( t ) ) {
1362 mdata_table_lock( t );
1370void* mdata_table_get_void(
const struct MDATA_TABLE* t,
const char* key ) {
1372 void* value_out = NULL;
1375 assert( mdata_table_is_locked( t ) );
1377#if MDATA_TRACE_LVL > 0
1378 debug_printf( MDATA_TRACE_LVL,
1379 "searching for key: %s (%u)", key, key_hash );
1382 idx = _mdata_table_hunt_index( t, key, 0, 0 );
1384 retval = MERROR_OVERFLOW;
1388 value_out = mdata_vector_get_void( &(t->data_cols[1]), idx );
1392 if( MERROR_OK != retval ) {
1401void* mdata_table_hash_get_void(
1402 struct MDATA_TABLE* t, uint32_t key_hash,
size_t key_sz
1405 void* value_out = NULL;
1408 assert( mdata_table_is_locked( t ) );
1410#if MDATA_TRACE_LVL > 0
1411 debug_printf( MDATA_TRACE_LVL,
1412 "searching for hash %u (" SIZE_T_FMT
")", key_hash, key_sz );
1415 idx = _mdata_table_hunt_index( t, NULL, key_hash, key_sz );
1417 retval = MERROR_OVERFLOW;
1421 value_out = mdata_vector_get_void( &(t->data_cols[1]), idx );
1425 if( MERROR_OK != retval ) {
1435 mdata_vector_free( &(t->data_cols[0]) );
1436 mdata_vector_free( &(t->data_cols[1]) );
uint16_t MERROR_RETVAL
Return type indicating function returns a value from this list.
Definition merror.h:19
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:68
A vector of uniformly-sized objects, stored contiguously.
Definition mdata.h:93
size_t ct_step
Number of items added when more space is needed.
Definition mdata.h:104
MAUG_MHANDLE data_h
Handle for allocated items (unlocked).
Definition mdata.h:96
size_t item_sz
Size, in bytes, of each item.
Definition mdata.h:109
size_t ct
Maximum number of items actually used.
Definition mdata.h:102
uint8_t * data_bytes
Handle for allocated items (locked).
Definition mdata.h:98
size_t ct_max
Maximum number of items currently allocated for.
Definition mdata.h:100
ssize_t locks
Lock count, if MDATA_VECTOR_FLAG_REFCOUNT is enabled.
Definition mdata.h:111