maug
Quick and dirty C mini-augmentation library.
Loading...
Searching...
No Matches
mdata.h
Go to the documentation of this file.
1
2#ifndef MDATA_H
3#define MDATA_H
4
12
13#ifndef MDATA_TRACE_LVL
14# define MDATA_TRACE_LVL 0
15#endif /* !MDATA_TRACE_LVL */
16
21
30#define MDATA_VECTOR_FLAG_REFCOUNT 0x01
31
32#define MDATA_VECTOR_FLAG_IS_LOCKED 0x02
33
34#ifndef MDATA_VECTOR_INIT_STEP_SZ
39# define MDATA_VECTOR_INIT_STEP_SZ 10
40#endif /* !MDATA_VECTOR_INIT_STEP_SZ */
41
43
50
51typedef ssize_t mdata_strpool_idx_t;
52
62 size_t sz;
63 MAUG_MHANDLE str_h;
64 size_t str_sz;
65 size_t str_sz_max;
66};
67 /* mdata_strpool */
69
75
87 size_t sz;
88 uint8_t flags;
90 MAUG_MHANDLE data_h;
92 uint8_t* data_bytes;
94 size_t ct_max;
96 size_t ct;
98 size_t ct_step;
103 size_t item_sz;
105 ssize_t locks;
106};
107 /* mdata_vector */
109
114
116 struct MDATA_VECTOR data_cols[2];
117 size_t key_sz;
118};
119
121
126
127ssize_t mdata_strpool_find(
128 struct MDATA_STRPOOL* strpool, const char* str, size_t str_sz );
129
130MAUG_MHANDLE mdata_strpool_extract( struct MDATA_STRPOOL* s, size_t i );
131
132ssize_t mdata_strpool_append(
133 struct MDATA_STRPOOL* strpool, const char* str, size_t str_sz );
134
135MERROR_RETVAL mdata_strpool_alloc(
136 struct MDATA_STRPOOL* strpool, size_t alloc_sz );
137
138void mdata_strpool_free( struct MDATA_STRPOOL* strpool );
139
141
146
161 struct MDATA_VECTOR* v, const void* item, size_t item_sz );
162
169
178void* mdata_vector_get_void( struct MDATA_VECTOR* v, size_t idx );
179
180MERROR_RETVAL mdata_vector_copy(
181 struct MDATA_VECTOR* v_dest, struct MDATA_VECTOR* v_src );
182
188 struct MDATA_VECTOR* v, size_t item_sz, size_t item_ct_init );
189
190void mdata_vector_free( struct MDATA_VECTOR* v );
191 /* mdata_vector */
193
198
199MERROR_RETVAL mdata_table_set(
200 struct MDATA_TABLE* t, const char* key, size_t key_sz,
201 void* value, size_t value_sz );
202
203MERROR_RETVAL mdata_table_get_void(
204 struct MDATA_TABLE* t, const char* key, void** value_out, size_t value_sz );
205
207
212
213#define mdata_strpool_sz( strpool ) ((strpool)->str_sz_max)
214
215#define mdata_strpool_lock( strpool, ptr ) \
216 maug_mlock( (strpool)->str_h, ptr ); \
217 maug_cleanup_if_null_lock( char*, ptr );
218
219#define mdata_strpool_unlock( strpool, ptr ) \
220 if( NULL != ptr ) { \
221 maug_munlock( (strpool)->str_h, ptr ); \
222 }
223 /* mdata_strpool */
225
230
239#define mdata_vector_lock( v ) \
240 if( \
241 mdata_vector_get_flag( v, MDATA_VECTOR_FLAG_REFCOUNT ) && \
242 0 < (v)->locks \
243 ) { \
244 (v)->locks++; \
245 debug_printf( MDATA_TRACE_LVL, "vector " #v " locks: " SSIZE_T_FMT, \
246 (v)->locks ); \
247 } else { \
248 assert( !mdata_vector_is_locked( v ) ); \
249 if( mdata_vector_is_locked( v ) ) { \
250 error_printf( "attempting to double-lock vector!" ); \
251 retval = MERROR_OVERFLOW; \
252 goto cleanup; \
253 } \
254 maug_mlock( (v)->data_h, (v)->data_bytes ); \
255 maug_cleanup_if_null_lock( uint8_t*, (v)->data_bytes ); \
256 (v)->flags |= MDATA_VECTOR_FLAG_IS_LOCKED; \
257 debug_printf( MDATA_TRACE_LVL, "locked vector " #v ); \
258 }
259
265#define mdata_vector_unlock( v ) \
266 if( \
267 mdata_vector_get_flag( v, MDATA_VECTOR_FLAG_REFCOUNT ) && \
268 0 < (v)->locks \
269 ) { \
270 (v)->locks--; \
271 debug_printf( MDATA_TRACE_LVL, "vector " #v " locks: " SSIZE_T_FMT, \
272 (v)->locks ); \
273 } \
274 if( 0 == (v)->locks && NULL != (v)->data_bytes ) { \
275 assert( mdata_vector_is_locked( v ) ); \
276 maug_munlock( (v)->data_h, (v)->data_bytes ); \
277 (v)->flags &= ~MDATA_VECTOR_FLAG_IS_LOCKED; \
278 debug_printf( MDATA_TRACE_LVL, "unlocked vector " #v ); \
279 }
280
281#define mdata_vector_get( v, idx, type ) \
282 ((type*)mdata_vector_get_void( v, idx ))
283
284#define mdata_vector_get_last( v, type ) \
285 (0 < mdata_vector_ct( v ) ? \
286 ((type*)mdata_vector_get_void( v, \
287 mdata_vector_ct( v ) - 1 )) : NULL)
288
289#define mdata_vector_remove_last( v ) \
290 (0 < mdata_vector_ct( v ) ? \
291 (mdata_vector_remove( v, mdata_vector_ct( v ) - 1 )) : MERROR_OVERFLOW)
292
293#define mdata_vector_set_ct_step( v, step ) \
294 (v)->ct_step = step;
295
303#define mdata_vector_ct( v ) ((v)->ct)
304
309#define mdata_vector_sz( v ) (((v)->ct_max) * ((v)->item_sz))
310
315#define mdata_vector_fill( v, ct_new, sz ) \
316 retval = mdata_vector_alloc( v, sz, ct_new ); \
317 maug_cleanup_if_not_ok(); \
318 (v)->ct = (ct_new);
319
320#define mdata_vector_is_locked( v ) \
321 (MDATA_VECTOR_FLAG_IS_LOCKED == \
322 (MDATA_VECTOR_FLAG_IS_LOCKED & (v)->flags))
323
324/* TODO: Implement insert sorting. */
325#define mdata_vector_insert_sort( v, i, t, field )
326
327/* TODO: Implement sorting. */
328#define mdata_vector_sort( v, t, field )
329
330#define _mdata_vector_item_ptr( v, idx ) \
331 (&((v)->data_bytes[((idx) * ((v)->item_sz))]))
332
333#define mdata_vector_set_flag( v, flag ) (v)->flags |= (flag)
334
335#define mdata_vector_get_flag( v, flag ) ((flag) == ((v)->flags & (flag)))
336 /* mdata_vector */
338
339#define mdata_retval( idx ) (0 > idx ? ((idx) * -1) : MERROR_OK)
340
341#ifdef MDATA_C
342
343ssize_t mdata_strpool_find(
344 struct MDATA_STRPOOL* strpool, const char* str, size_t str_sz
345) {
346 MERROR_RETVAL retval = MERROR_OK;
347 ssize_t i = 0;
348 char* strpool_p = NULL;
349 size_t* p_str_iter_sz = NULL;
350
351 if( (MAUG_MHANDLE)NULL == strpool->str_h ) {
352 error_printf( "strpool not allocated!" );
353 i = -1;
354 goto cleanup;
355 }
356
357 maug_mlock( strpool->str_h, strpool_p );
358
359 while( i < strpool->str_sz ) {
360 p_str_iter_sz = (size_t*)&(strpool_p[i]);
361 if(
362 0 == strncmp( &(strpool_p[i + sizeof( size_t )]), str, str_sz + 1 )
363 ) {
364 /* String found. Advance past the size before returning. */
365 i += sizeof( size_t );
366 debug_printf( MDATA_TRACE_LVL,
367 "found strpool_idx: " SIZE_T_FMT " (" SIZE_T_FMT " bytes): \"%s\"",
368 i, *p_str_iter_sz, &(strpool_p[i]) );
369
370 goto cleanup;
371 } else {
372 debug_printf( MDATA_TRACE_LVL,
373 "skipping strpool_idx: " SIZE_T_FMT " (" SIZE_T_FMT
374 " bytes): \"%s\"",
375 i + sizeof( size_t ), *p_str_iter_sz,
376 &(strpool_p[i + sizeof( size_t )]) );
377 }
378 i += *p_str_iter_sz;
379 }
380
381 /* String not found. */
382 i = -1;
383
384cleanup:
385
386 if( MERROR_OK != retval ) {
387 i = retval * -1;
388 }
389
390 if( NULL != strpool_p ) {
391 maug_munlock( strpool->str_h, strpool_p );
392 }
393
394 return i;
395}
396
397/* === */
398
399MAUG_MHANDLE mdata_strpool_extract( struct MDATA_STRPOOL* s, size_t i ) {
400 MERROR_RETVAL retval = MERROR_OK;
401 char* strpool = NULL;
402 MAUG_MHANDLE out_h = (MAUG_MHANDLE)NULL;
403 size_t out_sz = 0;
404 char* out_tmp = NULL;
405
406 mdata_strpool_lock( s, strpool );
407
408 out_sz = maug_strlen( &(strpool[i]) );
409 out_h = maug_malloc( out_sz + 1, 1 );
410 maug_cleanup_if_null_alloc( MAUG_MHANDLE, out_h );
411
412 maug_mlock( out_h, out_tmp );
413 maug_cleanup_if_null_lock( char*, out_tmp );
414
415 maug_mzero( out_tmp, out_sz + 1 );
416 maug_strncpy( out_tmp, &(strpool[i]), out_sz );
417
418cleanup:
419
420 if( NULL != out_tmp ) {
421 maug_munlock( out_h, out_tmp );
422 }
423
424 if( MERROR_OK != retval && (MAUG_MHANDLE)NULL != out_h ) {
425 maug_mfree( out_h );
426 }
427
428 if( NULL != strpool ) {
429 mdata_strpool_unlock( s, strpool );
430 }
431
432 return out_h;
433}
434
435/* === */
436
437ssize_t mdata_strpool_append(
438 struct MDATA_STRPOOL* strpool, const char* str, size_t str_sz
439) {
440 ssize_t idx_p_out = 0;
441 char* strpool_p = NULL;
442 MERROR_RETVAL retval = MERROR_OK;
443 size_t* p_str_sz = NULL;
444 size_t padding = 0;
445 size_t alloc_sz = 0;
446
447 if( 0 < strpool->str_sz ) {
448 /* Search the str_stable for an identical string and return that index.
449 */
450 idx_p_out = mdata_strpool_find( strpool, str, str_sz );
451 if( -1 != idx_p_out ) {
452 /* Found, or error returned. */
453 goto cleanup;
454 }
455 }
456
457 assert( 0 < str_sz );
458
459 /* Pad out allocated space so size_t is always aligned. */
460 padding = sizeof( size_t ) - ((str_sz + 1 /* NULL */) % sizeof( size_t ));
461 alloc_sz = sizeof( size_t ) + str_sz + 1 /* NULL */ + padding;
462 assert( 0 == alloc_sz % sizeof( size_t ) );
463
464 debug_printf( MDATA_TRACE_LVL,
465 "adding size_t (" SIZE_T_FMT " bytes) + string %s (" SIZE_T_FMT
466 " bytes) + 1 NULL + " SIZE_T_FMT " bytes padding to strpool...",
467 sizeof( size_t ), str, str_sz, padding );
468
469 retval = mdata_strpool_alloc( strpool, alloc_sz );
470 maug_cleanup_if_not_ok();
471
472 maug_mlock( strpool->str_h, strpool_p );
473 maug_cleanup_if_null_alloc( char*, strpool_p );
474
475 debug_printf( MDATA_TRACE_LVL,
476 "strpool (" SIZE_T_FMT " bytes) locked to: %p",
477 strpool->str_sz, strpool_p );
478
479 /* Add this string at the end of the string table. */
480 maug_strncpy( &(strpool_p[strpool->str_sz + sizeof( size_t )]), str, str_sz );
481 strpool_p[strpool->str_sz + sizeof( size_t ) + str_sz] = '\0';
482
483 /* Add the size of the string to the strpool. */
484 assert( 0 == strpool->str_sz % sizeof( size_t ) );
485 p_str_sz = (size_t*)&(strpool_p[strpool->str_sz]);
486 *p_str_sz = alloc_sz;
487
488 idx_p_out = strpool->str_sz + sizeof( size_t );
489
490 debug_printf(
491 MDATA_TRACE_LVL, "set strpool_idx: " SIZE_T_FMT ": \"%s\"",
492 strpool->str_sz, &(strpool_p[idx_p_out]) );
493
494 /* Set the string table cursor to the next available spot. */
495 strpool->str_sz += alloc_sz;
496
497cleanup:
498
499 if( MERROR_OK != retval ) {
500 idx_p_out = retval * -1;
501 }
502
503 if( NULL != strpool_p ) {
504 maug_munlock( strpool->str_h, strpool_p );
505 }
506
507 return idx_p_out;
508}
509
510/* === */
511
512MERROR_RETVAL mdata_strpool_alloc(
513 struct MDATA_STRPOOL* strpool, size_t alloc_sz
514) {
515 MERROR_RETVAL retval = MERROR_OK;
516 MAUG_MHANDLE str_h_new = (MAUG_MHANDLE)NULL;
517
518 if( (MAUG_MHANDLE)NULL == strpool->str_h ) {
519 debug_printf(
520 MDATA_TRACE_LVL, "creating string table of " SIZE_T_FMT " chars...",
521 alloc_sz );
522 assert( (MAUG_MHANDLE)NULL == strpool->str_h );
523 strpool->str_h = maug_malloc( alloc_sz, 1 );
524 maug_cleanup_if_null_alloc( MAUG_MHANDLE, strpool->str_h );
525 strpool->str_sz_max = alloc_sz;
526 strpool->sz = sizeof( struct MDATA_STRPOOL );
527
528 } else if( strpool->str_sz_max <= strpool->str_sz + alloc_sz ) {
529 while( strpool->str_sz_max <= strpool->str_sz + alloc_sz ) {
530 debug_printf(
531 MDATA_TRACE_LVL, "enlarging string table to " SIZE_T_FMT "...",
532 strpool->str_sz_max * 2 );
533 maug_mrealloc_test(
534 str_h_new, strpool->str_h, strpool->str_sz_max, (size_t)2 );
535 strpool->str_sz_max *= 2;
536 }
537 }
538
539cleanup:
540 return retval;
541}
542
543/* === */
544
545void mdata_strpool_free( struct MDATA_STRPOOL* strpool ) {
546 if( (MAUG_MHANDLE)NULL != strpool->str_h ) {
547 maug_mfree( strpool->str_h );
548 }
549}
550
551/* === */
552
553ssize_t mdata_vector_append(
554 struct MDATA_VECTOR* v, const void* item, size_t item_sz
555) {
556 MERROR_RETVAL retval = MERROR_OK;
557 ssize_t idx_out = -1;
558
559 if( 0 < v->item_sz && item_sz != v->item_sz ) {
560 error_printf( "attempting to add item of " SIZE_T_FMT " bytes to vector, "
561 "but vector is already sized for " SIZE_T_FMT "-byte items!",
562 item_sz, v->item_sz );
563 retval = MERROR_OVERFLOW;
564 goto cleanup;
565 }
566
567 mdata_vector_alloc( v, item_sz, v->ct_step );
568
569 /* Lock the vector to work in it a bit. */
570 mdata_vector_lock( v );
571
572 idx_out = v->ct;
573
574 if( NULL != item ) {
575 /* Copy provided item. */
576 debug_printf(
577 MDATA_TRACE_LVL, "inserting into vector at index: " SIZE_T_FMT,
578 idx_out );
579
580 memcpy( _mdata_vector_item_ptr( v, idx_out ), item, item_sz );
581 }
582
583 v->ct++;
584
585cleanup:
586
587 if( MERROR_OK != retval ) {
588 error_printf( "error adding to vector: %d", retval );
589 idx_out = retval * -1;
590 assert( 0 > idx_out );
591 }
592
593 mdata_vector_unlock( v );
594
595 return idx_out;
596}
597
598/* === */
599
600MERROR_RETVAL mdata_vector_remove( struct MDATA_VECTOR* v, size_t idx ) {
601 MERROR_RETVAL retval = MERROR_OK;
602 size_t i = 0;
603
604 if( NULL != v->data_bytes ) {
605 error_printf( "vector cannot be resized while locked!" );
606 retval = MERROR_ALLOC;
607 goto cleanup;
608 }
609
610 if( v->ct <= idx ) {
611 error_printf( "index out of range!" );
612 retval = MERROR_OVERFLOW;
613 goto cleanup;
614 }
615
616 debug_printf( MDATA_TRACE_LVL, "removing vector item: " SIZE_T_FMT, idx );
617
618 assert( 0 < v->item_sz );
619
620 mdata_vector_lock( v );
621
622 for( i = idx ; v->ct > i + 1 ; i++ ) {
623 debug_printf( MDATA_TRACE_LVL,
624 "shifting " SIZE_T_FMT "-byte vector item " SIZE_T_FMT " up by 1...",
625 v->item_sz, i );
626 memcpy(
627 &(v->data_bytes[i * v->item_sz]),
628 &(v->data_bytes[(i + 1) * v->item_sz]),
629 v->item_sz );
630 }
631
632 v->ct--;
633
634cleanup:
635
636 mdata_vector_unlock( v );
637
638 return retval;
639}
640
641/* === */
642
643void* mdata_vector_get_void( struct MDATA_VECTOR* v, size_t idx ) {
644
645 debug_printf( MDATA_TRACE_LVL,
646 "getting vector item " SIZE_T_FMT " (of " SIZE_T_FMT ")...",
647 idx, v->ct );
648
649 assert( 0 == v->ct || NULL != v->data_bytes );
650
651 if( idx >= v->ct ) {
652 return NULL;
653 } else {
654 return _mdata_vector_item_ptr( v, idx );
655 }
656}
657
658/* === */
659
660MERROR_RETVAL mdata_vector_copy(
661 struct MDATA_VECTOR* v_dest, struct MDATA_VECTOR* v_src
662) {
663 MERROR_RETVAL retval = MERROR_OK;
664
665 if( NULL != v_src->data_bytes ) {
666 error_printf( "vector cannot be copied while locked!" );
667 retval = MERROR_ALLOC;
668 goto cleanup;
669 }
670
671 assert( 0 < v_src->item_sz );
672 assert( 0 < v_src->ct_max );
673
674 v_dest->ct_max = v_src->ct_max;
675 v_dest->ct = v_src->ct;
676 v_dest->item_sz = v_src->item_sz;
677 debug_printf(
678 MDATA_TRACE_LVL,
679 "copying " SIZE_T_FMT " vector of " SIZE_T_FMT "-byte nodes...",
680 v_src->ct_max, v_src->item_sz );
681 assert( (MAUG_MHANDLE)NULL == v_dest->data_h );
682 v_dest->data_h = maug_malloc( v_src->ct_max, v_src->item_sz );
683 maug_cleanup_if_null_alloc( MAUG_MHANDLE, v_dest->data_h );
684
685 mdata_vector_lock( v_dest );
686 mdata_vector_lock( v_src );
687
688 memcpy( v_dest->data_bytes, v_src->data_bytes,
689 v_src->ct_max * v_src->item_sz );
690
691cleanup:
692
693 mdata_vector_unlock( v_src );
694 mdata_vector_unlock( v_dest );
695
696 return retval;
697}
698
699/* === */
700
702 struct MDATA_VECTOR* v, size_t item_sz, size_t item_ct_init
703) {
704 MERROR_RETVAL retval = MERROR_OK;
705 MAUG_MHANDLE data_h_new = (MAUG_MHANDLE)NULL;
706 size_t new_ct = item_ct_init,
707 new_bytes_start = 0,
708 new_bytes_sz = 0;
709
710 if( NULL != v->data_bytes ) {
711 error_printf( "vector cannot be resized while locked!" );
712 retval = MERROR_ALLOC;
713 goto cleanup;
714 }
715
716 /* Make sure there are free nodes. */
717 if( (MAUG_MHANDLE)NULL == v->data_h ) {
718 assert( 0 == v->ct_max );
719
720 if( 0 < item_ct_init ) {
721 debug_printf( MDATA_TRACE_LVL, "setting step sz: " SIZE_T_FMT,
722 item_ct_init );
723 v->ct_step = item_ct_init;
724 } else if( 0 == v->ct_step ) {
725 debug_printf( MDATA_TRACE_LVL, "setting step sz: %d",
726 MDATA_VECTOR_INIT_STEP_SZ );
727 v->ct_step = MDATA_VECTOR_INIT_STEP_SZ;
728 }
729 v->ct_max = v->ct_step;
730 debug_printf(
731 MDATA_TRACE_LVL,
732 "creating " SIZE_T_FMT " vector of " SIZE_T_FMT "-byte nodes...",
733 v->ct_max, item_sz );
734 assert( (MAUG_MHANDLE)NULL == v->data_h );
735 v->data_h = maug_malloc( v->ct_max, item_sz );
736 v->item_sz = item_sz;
737 maug_cleanup_if_null_alloc( MAUG_MHANDLE, v->data_h );
738
739 /* Zero out the new space. */
740 mdata_vector_lock( v );
741 maug_mzero( v->data_bytes, v->ct_max * item_sz );
742 mdata_vector_unlock( v );
743
744 v->sz = sizeof( struct MDATA_VECTOR );
745
746 } else if( v->ct_max <= v->ct + 1 || v->ct_max <= item_ct_init ) {
747 assert( item_sz == v->item_sz );
748
749 /* Use ct * 2 or ct_init... whichever is larger! */
750 if( item_ct_init < v->ct_max + v->ct_step ) {
751 assert( v->ct_max + v->ct_step > v->ct_max );
752 new_ct = v->ct_max + v->ct_step;
753 }
754
755 /* Perform the resize. */
756 debug_printf(
757 MDATA_TRACE_LVL, "enlarging vector to " SIZE_T_FMT "...",
758 new_ct );
759 maug_mrealloc_test( data_h_new, v->data_h, new_ct, item_sz );
760
761 /* Zero out the new space. */
762 new_bytes_start = v->ct_max * v->item_sz;
763 assert( new_bytes_start >= v->ct_max );
764 new_bytes_sz = (new_ct * v->item_sz) - new_bytes_start;
765 assert( new_bytes_sz >= v->item_sz );
767 maug_mzero( &(v->data_bytes[new_bytes_start]), new_bytes_sz );
769
770 v->ct_max = new_ct;
771 }
772
773cleanup:
774
775 return retval;
776}
777
778/* === */
779
780void mdata_vector_free( struct MDATA_VECTOR* v ) {
781 if( 0 < v->ct_max ) {
782 maug_mfree( v->data_h );
783 }
784 v->ct = 0;
785 v->ct_max = 0;
786 v->item_sz = 0;
787}
788
789/* === */
790
791MERROR_RETVAL mdata_table_set(
792 struct MDATA_TABLE* t, const char* key, size_t key_sz,
793 void* value, size_t value_sz
794) {
795 MERROR_RETVAL retval = MERROR_OK;
796 ssize_t idx_key = -1;
797 ssize_t idx_val = -1;
798
799 /* TODO: This has all kinds of issues, obviously. At some point, turn it
800 * into a proper hashtable that can operate in tiny conditions!
801 */
802
803 assert(
804 mdata_vector_ct( &(t->data_cols[0]) ) ==
805 mdata_vector_ct( &(t->data_cols[1]) ) );
806
807 idx_key = mdata_vector_append( &(t->data_cols[0]), key, key_sz + 1 );
808 assert( 0 <= idx_key );
809
810 /* TODO: Atomicity: remove key if value fails! */
811
812 idx_val = mdata_vector_append( &(t->data_cols[1]), value, value_sz );
813 assert( 0 <= idx_val );
814
815/* cleanup: */
816
817 /* TODO: Set retval! */
818
819 return retval;
820}
821
822/* === */
823
824MERROR_RETVAL mdata_table_get_void(
825 struct MDATA_TABLE* t, const char* key, void** value_out, size_t value_sz
826) {
827 MERROR_RETVAL retval = MERROR_OK;
828 char* c = NULL;
829 size_t i = 0;
830
831 assert( NULL == *value_out );
832
833 mdata_vector_lock( &(t->data_cols[0]) );
834 mdata_vector_lock( &(t->data_cols[1]) );
835 for( i = 0 ; mdata_vector_ct( &(t->data_cols[0]) ) > i ; i++ ) {
836 /* TODO: Maybe strpool would be better for this? */
837 c = mdata_vector_get( &(t->data_cols[0]), i, char );
838 assert( NULL != c );
839 if( 0 == strncmp( key, c, t->data_cols[0].item_sz - 1 ) ) {
840 *value_out = mdata_vector_get_void( &(t->data_cols[1]), i );
841 goto cleanup;
842 }
843 }
844
845 /* Not found! */
846 retval = MERROR_OVERFLOW;
847
848cleanup:
849
850 mdata_vector_unlock( &(t->data_cols[0]) );
851 mdata_vector_unlock( &(t->data_cols[1]) );
852
853 return retval;
854}
855
856#endif /* MDATA_C */
857 /* maug_data */
859
860#endif /* MDATA_H */
861
int MERROR_RETVAL
Return type indicating function returns a value from this list.
Definition merror.h:19
#define mdata_vector_lock(v)
Lock the vector. This should be done when items from the vector are actively being referenced,...
Definition mdata.h:239
void * mdata_vector_get_void(struct MDATA_VECTOR *v, size_t idx)
Get a generic pointer to an item in the MDATA_VECTOR.
#define mdata_vector_unlock(v)
Unlock the vector so items may be added and removed.
Definition mdata.h:265
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.
#define mdata_vector_ct(v)
Number of items of MDATA_VECTOR::item_sz bytes actively stored in this vector.
Definition mdata.h:303
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:60
size_t sz
Size of this struct (useful for serializing).
Definition mdata.h:62
Definition mdata.h:115
A vector of uniformly-sized objects, stored contiguously.
Definition mdata.h:85
size_t ct_step
Number of items added when more space is needed.
Definition mdata.h:98
MAUG_MHANDLE data_h
Handle for allocated items (unlocked).
Definition mdata.h:90
size_t item_sz
Size, in bytes, of each item.
Definition mdata.h:103
size_t sz
Size of this struct (useful for serializing).
Definition mdata.h:87
size_t ct
Maximum number of items actually used.
Definition mdata.h:96
uint8_t * data_bytes
Handle for allocated items (locked).
Definition mdata.h:92
size_t ct_max
Maximum number of items currently allocated for.
Definition mdata.h:94
ssize_t locks
Lock count, if MDATA_VECTOR_FLAG_REFCOUNT is enabled.
Definition mdata.h:105