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 ssize_t mdata_strpool_idx_t;
124 char string[MDATA_TABLE_KEY_SZ_MAX + 1];
148mdata_strpool_idx_t mdata_strpool_find(
158mdata_strpool_idx_t mdata_strpool_append(
159 struct MDATA_STRPOOL* sp,
const char* str,
size_t str_sz, uint8_t flags );
192ssize_t mdata_vector_insert(
226uint32_t mdata_hash(
const char* token,
size_t token_sz );
235 void* cb_data,
size_t cb_data_sz,
size_t idx );
243 mdata_table_iter_t cb,
void* cb_data,
size_t cb_data_sz );
247 void* value,
size_t value_sz );
252void* mdata_table_get_void(
const struct MDATA_TABLE* t,
const char* key );
254void* mdata_table_hash_get_void(
255 struct MDATA_TABLE* t, uint32_t key_hash,
size_t key_sz );
261#if MDATA_TRACE_LVL > 0
262# define mdata_debug_printf( fmt, ... ) \
263 debug_printf( MDATA_TRACE_LVL, fmt, __VA_ARGS__ );
265# define mdata_debug_printf( fmt, ... )
273#define mdata_strpool_sz( sp ) ((sp)->str_sz_max)
275#define mdata_strpool_is_locked( sp ) \
276 (MDATA_STRPOOL_FLAG_IS_LOCKED == \
277 (MDATA_STRPOOL_FLAG_IS_LOCKED & (sp)->flags))
279#define mdata_strpool_lock( sp ) \
280 assert( NULL == (sp)->str_p ); \
281 maug_mlock( (sp)->str_h, (sp)->str_p ); \
282 maug_cleanup_if_null_lock( char*, (sp)->str_p ); \
283 (sp)->flags |= MDATA_STRPOOL_FLAG_IS_LOCKED;
285#define mdata_strpool_unlock( sp ) \
286 if( NULL != (sp)->str_p ) { \
287 maug_munlock( (sp)->str_h, (sp)->str_p ); \
288 (sp)->flags &= ~MDATA_STRPOOL_FLAG_IS_LOCKED; \
291#define mdata_strpool_get( sp, idx ) \
292 ((idx >= 0 && idx < (sp)->str_sz) ? &((sp)->str_p[idx]) : NULL)
294#define mdata_strpool_padding( str_sz ) \
295 (sizeof( size_t ) - ((str_sz + 1 ) % sizeof( size_t )))
312#define mdata_vector_lock( v ) \
313 if( (MAUG_MHANDLE)NULL == (v)->data_h && NULL == (v)->data_bytes ) { \
314 mdata_debug_printf( "locking empty vector..." ); \
315 (v)->flags |= MDATA_VECTOR_FLAG_IS_LOCKED; \
317 mdata_vector_get_flag( v, MDATA_VECTOR_FLAG_REFCOUNT ) && \
321 mdata_debug_printf( "vector " #v " locks: " SSIZE_T_FMT, (v)->locks ); \
324 if( mdata_vector_is_locked( v ) ) { \
325 error_printf( "attempting to double-lock vector!" ); \
326 retval = MERROR_OVERFLOW; \
329 if( (MAUG_MHANDLE)NULL == (v)->data_h ) { \
330 error_printf( "invalid data handle!" ); \
331 retval = MERROR_ALLOC; \
334 maug_mlock( (v)->data_h, (v)->data_bytes ); \
335 maug_cleanup_if_null_lock( uint8_t*, (v)->data_bytes ); \
336 (v)->flags |= MDATA_VECTOR_FLAG_IS_LOCKED; \
337 mdata_debug_printf( "locked vector " #v ); \
345#define mdata_vector_unlock( v ) \
346 if( (MAUG_MHANDLE)NULL == (v)->data_h && NULL == (v)->data_bytes ) { \
347 mdata_debug_printf( "locking empty vector..." ); \
348 (v)->flags &= ~MDATA_VECTOR_FLAG_IS_LOCKED; \
351 mdata_vector_get_flag( v, MDATA_VECTOR_FLAG_REFCOUNT ) && \
355 mdata_debug_printf( "vector " #v " locks: " SSIZE_T_FMT, \
358 if( 0 == (v)->locks && NULL != (v)->data_bytes ) { \
359 assert( mdata_vector_is_locked( v ) ); \
360 maug_munlock( (v)->data_h, (v)->data_bytes ); \
361 (v)->flags &= ~MDATA_VECTOR_FLAG_IS_LOCKED; \
362 mdata_debug_printf( "unlocked vector " #v ); \
366#define mdata_vector_get( v, idx, type ) \
367 ((type*)mdata_vector_get_void( v, idx ))
369#define mdata_vector_get_last( v, type ) \
370 (0 < mdata_vector_ct( v ) ? \
371 ((type*)mdata_vector_get_void( v, \
372 mdata_vector_ct( v ) - 1 )) : NULL)
374#define mdata_vector_remove_last( v ) \
375 (0 < mdata_vector_ct( v ) ? \
376 (mdata_vector_remove( v, mdata_vector_ct( v ) - 1 )) : MERROR_OVERFLOW)
378#define mdata_vector_set_ct_step( v, step ) \
388#define mdata_vector_ct( v ) ((v)->ct)
394#define mdata_vector_sz( v ) (((v)->ct_max) * ((v)->item_sz))
400#define mdata_vector_fill( v, ct_new, sz ) \
401 retval = mdata_vector_alloc( v, sz, ct_new ); \
402 maug_cleanup_if_not_ok(); \
405#define mdata_vector_is_locked( v ) \
406 (MDATA_VECTOR_FLAG_IS_LOCKED == \
407 (MDATA_VECTOR_FLAG_IS_LOCKED & (v)->flags))
410#define mdata_vector_insert_sort( v, i, t, field )
413#define mdata_vector_sort( v, t, field )
415#define _mdata_vector_item_ptr( v, idx ) \
416 (&((v)->data_bytes[((idx) * ((v)->item_sz))]))
418#define mdata_vector_set_flag( v, flag ) (v)->flags |= (flag)
420#define mdata_vector_get_flag( v, flag ) ((flag) == ((v)->flags & (flag)))
429#define mdata_table_is_locked( t ) \
430 (mdata_vector_is_locked( &((t)->data_cols[0]) ))
432#define mdata_table_get( t, key, type ) \
433 ((type*)mdata_table_get_void( t, key ))
435#define mdata_table_hash_get( t, hash, sz, type ) \
436 ((type*)mdata_table_hash_get_void( t, hash, sz ))
438#define mdata_table_ct( t ) ((t)->data_cols[0].ct)
442#define mdata_retval( idx ) (0 > idx ? ((idx) * -1) : MERROR_OK)
450 mdata_strpool_idx_t i = 0;
453 if( !mdata_strpool_is_locked( sp ) ) {
454 mdata_strpool_lock( sp );
458 for( i = 0 ; sp->str_sz > i ; i += (size_t)*(&(sp->str_p[i])) ) {
468 mdata_strpool_unlock( sp );
478 char* strpool_p = NULL;
480 maug_mlock( sp->str_h, strpool_p );
482 for( i = 0 ; mdata_strpool_sz( sp ) > i ; i++ ) {
483 printf(
"0x%02x ", strpool_p[i] );
487 if( NULL != strpool_p ) {
488 maug_munlock( sp->str_h, strpool_p );
494ssize_t mdata_strpool_find(
495 struct MDATA_STRPOOL* strpool,
const char* str,
size_t str_sz
499 char* strpool_p = NULL;
500 size_t* p_str_iter_sz = NULL;
502 if( (MAUG_MHANDLE)NULL == strpool->str_h ) {
503 error_printf(
"strpool not allocated!" );
508 maug_mlock( strpool->str_h, strpool_p );
510 while( i < strpool->str_sz ) {
511 p_str_iter_sz = (
size_t*)&(strpool_p[i]);
513 0 == strncmp( &(strpool_p[i +
sizeof(
size_t )]), str, str_sz + 1 )
516 i +=
sizeof( size_t );
517#if MDATA_TRACE_LVL > 0
518 debug_printf( MDATA_TRACE_LVL,
519 "found strpool_idx: " SIZE_T_FMT
" (" SIZE_T_FMT
" bytes): \"%s\"",
520 i, *p_str_iter_sz, &(strpool_p[i]) );
524#if MDATA_TRACE_LVL > 0
526 debug_printf( MDATA_TRACE_LVL,
527 "skipping strpool_idx: " SIZE_T_FMT
" (" SIZE_T_FMT
529 i +
sizeof(
size_t ), *p_str_iter_sz,
530 &(strpool_p[i +
sizeof(
size_t )]) );
541 if( MERROR_OK != retval ) {
545 if( NULL != strpool_p ) {
546 maug_munlock( strpool->str_h, strpool_p );
558 MAUG_MHANDLE out_h = (MAUG_MHANDLE)NULL;
560 char* out_tmp = NULL;
562 char* str_src = NULL;
564 if( !mdata_strpool_is_locked( sp ) ) {
565 mdata_strpool_lock( sp );
569 str_src = mdata_strpool_get( sp, idx );
570 if( NULL == str_src ) {
571 error_printf(
"invalid strpool index: " SSIZE_T_FMT, idx );
572 retval = MERROR_OVERFLOW;
576 out_sz = maug_strlen( str_src );
577 out_h = maug_malloc( out_sz + 1, 1 );
578 maug_cleanup_if_null_alloc( MAUG_MHANDLE, out_h );
580 maug_mlock( out_h, out_tmp );
581 maug_cleanup_if_null_lock(
char*, out_tmp );
583 maug_mzero( out_tmp, out_sz + 1 );
584 maug_strncpy( out_tmp, str_src, out_sz );
588 if( NULL != out_tmp ) {
589 maug_munlock( out_h, out_tmp );
592 if( MERROR_OK != retval && (MAUG_MHANDLE)NULL != out_h ) {
597 mdata_strpool_unlock( sp );
605ssize_t mdata_strpool_append(
606 struct MDATA_STRPOOL* strpool,
const char* str,
size_t str_sz, uint8_t flags
608 mdata_strpool_idx_t idx_p_out = 0;
609 char* strpool_p = NULL;
611 size_t* p_str_sz = NULL;
615 error_printf(
"attempted to add zero-length string!" );
616 retval = MERROR_OVERFLOW;
621 0 < strpool->str_sz &&
622 MDATA_STRPOOL_FLAG_DEDUPE == (MDATA_STRPOOL_FLAG_DEDUPE & flags)
626 idx_p_out = mdata_strpool_find( strpool, str, str_sz );
627 if( -1 != idx_p_out ) {
629#if MDATA_TRACE_LVL > 0
630 debug_printf( MDATA_TRACE_LVL,
631 "found duplicate string for add at index: " SSIZE_T_FMT,
639 alloc_sz =
sizeof( size_t ) + str_sz + 1 +
640 mdata_strpool_padding( str_sz );
641 assert( 0 == alloc_sz %
sizeof(
size_t ) );
643#if MDATA_TRACE_LVL > 0
644 debug_printf( MDATA_TRACE_LVL,
645 "adding size_t (" SIZE_T_FMT
" bytes) + string %s (" SIZE_T_FMT
646 " bytes) + 1 NULL + " SIZE_T_FMT
" bytes padding to strpool...",
647 sizeof(
size_t ), str, str_sz, mdata_strpool_padding( str_sz ) );
650 retval = mdata_strpool_alloc( strpool, alloc_sz );
651 maug_cleanup_if_not_ok();
653 maug_mlock( strpool->str_h, strpool_p );
654 maug_cleanup_if_null_alloc(
char*, strpool_p );
656#if MDATA_TRACE_LVL > 0
657 debug_printf( MDATA_TRACE_LVL,
658 "strpool (" SIZE_T_FMT
" bytes) locked to: %p",
659 strpool->str_sz, strpool_p );
664 &(strpool_p[strpool->str_sz +
sizeof(
size_t )]), str, str_sz );
665 strpool_p[strpool->str_sz +
sizeof( size_t ) + str_sz] =
'\0';
668 assert( 0 == strpool->str_sz %
sizeof(
size_t ) );
669 p_str_sz = (
size_t*)&(strpool_p[strpool->str_sz]);
670 *p_str_sz = alloc_sz;
672 idx_p_out = strpool->str_sz +
sizeof( size_t );
674#if MDATA_TRACE_LVL > 0
675 debug_printf( MDATA_TRACE_LVL,
"set strpool_idx: " SIZE_T_FMT
": \"%s\"",
676 strpool->str_sz, &(strpool_p[idx_p_out]) );
680 strpool->str_sz += alloc_sz;
684 if( MERROR_OK != retval ) {
685 idx_p_out = retval * -1;
688 if( NULL != strpool_p ) {
689 maug_munlock( strpool->str_h, strpool_p );
701 MAUG_MHANDLE str_h_new = (MAUG_MHANDLE)NULL;
703 if( (MAUG_MHANDLE)NULL == strpool->str_h ) {
704#if MDATA_TRACE_LVL > 0
706 MDATA_TRACE_LVL,
"creating string pool of " SIZE_T_FMT
" chars...",
709 assert( (MAUG_MHANDLE)NULL == strpool->str_h );
710 strpool->str_h = maug_malloc( alloc_sz, 1 );
711 maug_cleanup_if_null_alloc( MAUG_MHANDLE, strpool->str_h );
712 strpool->str_sz_max = alloc_sz;
714 }
else if( strpool->str_sz_max <= strpool->str_sz + alloc_sz ) {
715 while( strpool->str_sz_max <= strpool->str_sz + alloc_sz ) {
716#if MDATA_TRACE_LVL > 0
718 MDATA_TRACE_LVL,
"enlarging string pool to " SIZE_T_FMT
"...",
719 strpool->str_sz_max * 2 );
722 str_h_new, strpool->str_h, strpool->str_sz_max, (
size_t)2 );
723 strpool->str_sz_max *= 2;
734 if( (MAUG_MHANDLE)NULL != strpool->str_h ) {
735 maug_mfree( strpool->str_h );
741ssize_t mdata_vector_append(
742 struct MDATA_VECTOR* v,
const void* item,
size_t item_sz
745 ssize_t idx_out = -1;
748 error_printf(
"attempting to add item of " SIZE_T_FMT
" bytes to vector, "
749 "but vector is already sized for " SIZE_T_FMT
"-byte items!",
751 retval = MERROR_OVERFLOW;
758 mdata_vector_lock( v );
764#if MDATA_TRACE_LVL > 0
766 MDATA_TRACE_LVL,
"inserting into vector at index: " SIZE_T_FMT,
770 memcpy( _mdata_vector_item_ptr( v, idx_out ), item, item_sz );
777 if( MERROR_OK != retval ) {
778 error_printf(
"error adding to vector: %d", retval );
779 idx_out = retval * -1;
780 assert( 0 > idx_out );
783 mdata_vector_unlock( v );
790ssize_t mdata_vector_insert(
791 struct MDATA_VECTOR* v,
const void* item, ssize_t idx,
size_t item_sz
799 error_printf(
"attempting to add item of " SIZE_T_FMT
" bytes to vector, "
800 "but vector is already sized for " SIZE_T_FMT
"-byte items!",
802 retval = MERROR_OVERFLOW;
807 error_printf(
"attempting to insert beyond end of vector!" );
808 retval = MERROR_OVERFLOW;
815 mdata_vector_lock( v );
817 for( i = v->
ct ; idx < i ; i-- ) {
818#if MDATA_TRACE_LVL > 0
819 debug_printf( MDATA_TRACE_LVL,
820 "copying vector item " SSIZE_T_FMT
" to " SSIZE_T_FMT
"...",
824 _mdata_vector_item_ptr( v, i ),
825 _mdata_vector_item_ptr( v, i - 1),
829#if MDATA_TRACE_LVL > 0
831 MDATA_TRACE_LVL,
"inserting into vector at index: " SIZE_T_FMT, idx );
835 memcpy( _mdata_vector_item_ptr( v, idx ), item, item_sz );
838 maug_mzero( _mdata_vector_item_ptr( v, idx ), item_sz );
845 if( MERROR_OK != retval ) {
846 error_printf(
"error adding to vector: %d", retval );
851 mdata_vector_unlock( v );
862 if( mdata_vector_is_locked( v ) ) {
863 error_printf(
"vector cannot be resized while locked!" );
864 retval = MERROR_ALLOC;
869 error_printf(
"index out of range!" );
870 retval = MERROR_OVERFLOW;
874#if MDATA_TRACE_LVL > 0
875 debug_printf( MDATA_TRACE_LVL,
"removing vector item: " SIZE_T_FMT, idx );
880 mdata_vector_lock( v );
882 for( i = idx ; v->
ct > i + 1 ; i++ ) {
883#if MDATA_TRACE_LVL > 0
884 debug_printf( MDATA_TRACE_LVL,
885 "shifting " SIZE_T_FMT
"-byte vector item " SIZE_T_FMT
" up by 1...",
898 mdata_vector_unlock( v );
905void* mdata_vector_get_void(
const struct MDATA_VECTOR* v,
size_t idx ) {
907#if MDATA_TRACE_LVL > 0
908 debug_printf( MDATA_TRACE_LVL,
909 "getting vector item " SIZE_T_FMT
" (of " SIZE_T_FMT
")...",
918 return _mdata_vector_item_ptr( v, idx );
930 error_printf(
"vector cannot be copied while locked!" );
931 retval = MERROR_ALLOC;
936 assert( 0 < v_src->
ct_max );
939 v_dest->
ct = v_src->
ct;
941#if MDATA_TRACE_LVL > 0
942 debug_printf( MDATA_TRACE_LVL,
943 "copying " SIZE_T_FMT
" vector of " SIZE_T_FMT
"-byte nodes...",
946 assert( (MAUG_MHANDLE)NULL == v_dest->
data_h );
948 maug_cleanup_if_null_alloc( MAUG_MHANDLE, v_dest->
data_h );
950 mdata_vector_lock( v_dest );
951 mdata_vector_lock( v_src );
958 mdata_vector_unlock( v_src );
959 mdata_vector_unlock( v_dest );
967 struct MDATA_VECTOR* v,
size_t item_sz,
size_t item_ct_init
970 MAUG_MHANDLE data_h_new = (MAUG_MHANDLE)NULL;
971 size_t new_ct = item_ct_init,
976 error_printf(
"vector cannot be resized while locked!" );
977 retval = MERROR_ALLOC;
982 if( (MAUG_MHANDLE)NULL == v->
data_h ) {
985 if( 0 < item_ct_init ) {
986#if MDATA_TRACE_LVL > 0
987 debug_printf( MDATA_TRACE_LVL,
"setting step sz: " SIZE_T_FMT,
992#if MDATA_TRACE_LVL > 0
993 debug_printf( MDATA_TRACE_LVL,
"setting step sz: %d",
994 MDATA_VECTOR_INIT_STEP_SZ );
996 v->
ct_step = MDATA_VECTOR_INIT_STEP_SZ;
999#if MDATA_TRACE_LVL > 0
1000 debug_printf( MDATA_TRACE_LVL,
1001 "creating " SIZE_T_FMT
" vector of " SIZE_T_FMT
"-byte nodes...",
1004 assert( (MAUG_MHANDLE)NULL == v->
data_h );
1006 assert( 0 < item_sz );
1008 maug_cleanup_if_null_alloc( MAUG_MHANDLE, v->
data_h );
1011 mdata_vector_lock( v );
1013 mdata_vector_unlock( v );
1017 }
else if( v->
ct_max <= v->
ct + 1 || v->
ct_max <= item_ct_init ) {
1027#if MDATA_TRACE_LVL > 0
1028 debug_printf( MDATA_TRACE_LVL,
"enlarging vector to " SIZE_T_FMT
"...",
1031 maug_mrealloc_test( data_h_new, v->
data_h, new_ct,
item_sz );
1035 assert( new_bytes_start >= v->
ct_max );
1036 new_bytes_sz = (new_ct * v->
item_sz) - new_bytes_start;
1037 assert( new_bytes_sz >= v->
item_sz );
1039 maug_mzero( &(v->
data_bytes[new_bytes_start]), new_bytes_sz );
1063uint32_t mdata_hash(
const char* token,
size_t token_sz ) {
1064 uint32_t hash_out = 2166136261u;
1068 for( i = 0 ; token_sz > i ; i++ ) {
1072 if(
'A' <= c &&
'Z' >= c ) {
1077 hash_out *= 16777619u;
1110 if( MERROR_OK != retval ) {
1111 assert( mdata_vector_is_locked( &(t->data_cols[0]) ) );
1119struct MDATA_TABLE_REPLACE_CADDY {
1120 struct MDATA_TABLE_KEY* key;
1126ssize_t _mdata_table_hunt_index(
1128 const char* key, uint32_t key_hash,
size_t key_sz
1133 if( 0 == mdata_table_ct( t ) ) {
1137 assert( mdata_vector_is_locked( &(t->data_cols[0]) ) );
1141 key_sz = maug_strlen( key );
1142 if( MDATA_TABLE_KEY_SZ_MAX < key_sz ) {
1143 key_sz = MDATA_TABLE_KEY_SZ_MAX;
1145 key_hash = mdata_hash( key, key_sz );
1150 for( i = 0 ; mdata_vector_ct( &(t->data_cols[0]) ) > i ; i++ ) {
1151 key_iter = mdata_vector_get(
1153 assert( NULL != key );
1155 key_iter->hash == key_hash &&
1156 key_iter->string_sz == key_sz
1158#if MDATA_TRACE_LVL > 0
1159 debug_printf( MDATA_TRACE_LVL,
"found value for key: %s", key );
1174 void* cb_data,
size_t cb_data_sz,
size_t idx
1177 struct MDATA_TABLE_REPLACE_CADDY* caddy =
1178 (
struct MDATA_TABLE_REPLACE_CADDY*)cb_data;
1181 key->hash == caddy->key->hash && key->string_sz == caddy->key->string_sz
1183#if MDATA_TRACE_LVL > 0
1184 debug_printf( MDATA_TRACE_LVL,
1185 "replacing table data for key %s (%u)...", key->string, key->hash );
1187 memcpy( data, caddy->data, data_sz );
1188 retval = MERROR_FILE;
1198 mdata_table_iter_t cb,
void* cb_data,
size_t cb_data_sz
1204 char* p_value = NULL;
1206 if( 0 == mdata_table_ct( t ) ) {
1210 if( !mdata_table_is_locked( t ) ) {
1211#if MDATA_TRACE_LVL > 0
1212 debug_printf( MDATA_TRACE_LVL,
"engaging table autolock..." );
1214 mdata_table_lock( t );
1219 for( i = 0 ; mdata_table_ct( t ) > i ; i++ ) {
1220 p_key = mdata_vector_get_void( &(t->data_cols[0]), i );
1221 assert( NULL != p_key );
1222 assert( 0 < p_key->string_sz );
1223 assert( p_key->string_sz == maug_strlen( p_key->string ) );
1224 p_value = mdata_vector_get_void( &(t->data_cols[1]), i );
1226 p_key, p_value, t->data_cols[1].
item_sz, cb_data, cb_data_sz, i );
1227 maug_cleanup_if_not_ok();
1233 mdata_table_unlock( t );
1243 void* value,
size_t value_sz
1246 ssize_t idx_key = -1;
1247 ssize_t idx_val = -1;
1249 struct MDATA_TABLE_REPLACE_CADDY caddy;
1251 assert( 0 < maug_strlen( key ) );
1253 assert( !mdata_table_is_locked( t ) );
1256 mdata_vector_ct( &(t->data_cols[0]) ) ==
1257 mdata_vector_ct( &(t->data_cols[1]) ) );
1261 maug_strncpy( key_tmp.string, key, MDATA_TABLE_KEY_SZ_MAX );
1262 if( maug_strlen( key ) > MDATA_TABLE_KEY_SZ_MAX + 1 ) {
1264 "key %s is longer than maximum key size! truncating to: %s",
1265 key, key_tmp.string );
1267 key_tmp.string_sz = strlen( key_tmp.string );
1268 key_tmp.hash = mdata_hash( key_tmp.string, key_tmp.string_sz );
1270#if MDATA_TRACE_LVL > 0
1271 debug_printf( MDATA_TRACE_LVL,
1272 "attempting to set key %s (%u) to " SIZE_T_FMT
"-byte value...",
1273 key_tmp.string, key_tmp.hash, value_sz );
1276 caddy.key = &key_tmp;
1281 retval = mdata_table_iter( t, _mdata_table_replace, &caddy,
1282 sizeof(
struct MDATA_TABLE_REPLACE_CADDY ) );
1283 if( MERROR_FILE == retval ) {
1291 idx_key = mdata_vector_append(
1293 assert( 0 <= idx_key );
1297 idx_val = mdata_vector_append( &(t->data_cols[1]), value, value_sz );
1298 assert( 0 <= idx_val );
1316#if MDATA_TRACE_LVL > 0
1317 debug_printf( MDATA_TRACE_LVL,
"unsetting table key: %s", key );
1323 if( !mdata_table_is_locked( t ) ) {
1324#if MDATA_TRACE_LVL > 0
1325 debug_printf( MDATA_TRACE_LVL,
"autolocking table vectors" );
1327 assert( !mdata_vector_is_locked( &(t->data_cols[0]) ) );
1328 assert( !mdata_vector_is_locked( &(t->data_cols[1]) ) );
1329 mdata_table_lock( t );
1333 idx = _mdata_table_hunt_index( t, key, 0, 0 );
1339 mdata_table_unlock( t );
1340 mdata_vector_remove( &(t->data_cols[0]), idx );
1341 mdata_vector_remove( &(t->data_cols[1]), idx );
1345 if( autolock && mdata_table_is_locked( t ) ) {
1346 mdata_table_unlock( t );
1347 }
else if( !autolock && !mdata_table_is_locked( t ) ) {
1348 mdata_table_lock( t );
1356void* mdata_table_get_void(
const struct MDATA_TABLE* t,
const char* key ) {
1358 void* value_out = NULL;
1361 assert( mdata_table_is_locked( t ) );
1363#if MDATA_TRACE_LVL > 0
1364 debug_printf( MDATA_TRACE_LVL,
1365 "searching for key: %s (%u)", key, key_hash );
1368 idx = _mdata_table_hunt_index( t, key, 0, 0 );
1370 retval = MERROR_OVERFLOW;
1374 value_out = mdata_vector_get_void( &(t->data_cols[1]), idx );
1378 if( MERROR_OK != retval ) {
1387void* mdata_table_hash_get_void(
1388 struct MDATA_TABLE* t, uint32_t key_hash,
size_t key_sz
1391 void* value_out = NULL;
1394 assert( mdata_table_is_locked( t ) );
1396#if MDATA_TRACE_LVL > 0
1397 debug_printf( MDATA_TRACE_LVL,
1398 "searching for hash %u (" SIZE_T_FMT
")", key_hash, key_sz );
1401 idx = _mdata_table_hunt_index( t, NULL, key_hash, key_sz );
1403 retval = MERROR_OVERFLOW;
1407 value_out = mdata_vector_get_void( &(t->data_cols[1]), idx );
1411 if( MERROR_OK != retval ) {
1421 mdata_vector_free( &(t->data_cols[0]) );
1422 mdata_vector_free( &(t->data_cols[1]) );
int 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.
#define mdata_vector_lock(v)
Lock the vector. This should be done when items from the vector are actively being referenced,...
Definition mdata.h:312
#define mdata_vector_unlock(v)
Unlock the vector so items may be added and removed.
Definition mdata.h:345
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:106
MAUG_MHANDLE data_h
Handle for allocated items (unlocked).
Definition mdata.h:98
size_t item_sz
Size, in bytes, of each item.
Definition mdata.h:111
size_t sz
Size of this struct (useful for serializing).
Definition mdata.h:95
size_t ct
Maximum number of items actually used.
Definition mdata.h:104
uint8_t * data_bytes
Handle for allocated items (locked).
Definition mdata.h:100
size_t ct_max
Maximum number of items currently allocated for.
Definition mdata.h:102
ssize_t locks
Lock count, if MDATA_VECTOR_FLAG_REFCOUNT is enabled.
Definition mdata.h:113