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 );
 
  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;
 
  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 );
 
  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;
 
  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 );
 
  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 );
 
  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...",
 
  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 );
 
  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",
 
 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 );
 
 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 );
 
 1053      maug_mzero( &(v->
data_bytes[new_bytes_start]), new_bytes_sz );
 
 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;
 
 1124   if( MERROR_OK != retval ) {
 
 1125      assert( mdata_vector_is_locked( &(t->data_cols[0]) ) );
 
 1133struct MDATA_TABLE_REPLACE_CADDY {
 
 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 );
 
 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++ ) {
 
 1235      assert( NULL != p_key );
 
 1236      assert( 0 < p_key->string_sz );
 
 1237      assert( p_key->string_sz == maug_strlen( p_key->string ) );
 
 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 ) );
 
 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 ) {
 
 1307   assert( 0 <= idx_key );
 
 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 );
 
 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;
 
 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;
 
 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
#define mdata_vector_lock(v)
Lock the vector. This should be done when items from the vector are actively being referenced,...
Definition: mdata.h:320
size_t ct_step
Number of items added when more space is needed.
Definition: mdata.h:104
#define mdata_vector_unlock(v)
Unlock the vector so items may be added and removed.
Definition: mdata.h:353
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
#define mdata_vector_ct(v)
Number of items of MDATA_VECTOR::item_sz bytes actively stored in this vector.
Definition: mdata.h:396
#define MDATA_VECTOR_INIT_STEP_SZ
Default initial value for MDATA_VECTOR::ct_step.
Definition: mdata.h:43
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