Loading [MathJax]/extensions/TeX/AMSsymbols.js
LAL 7.7.0.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
LALHashTblTest.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2016 Karl Wette
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with with program; see the file COPYING. If not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA
18 */
19
20#include <stdlib.h>
21#include <stdint.h>
22#include <gsl/gsl_rng.h>
23#include <gsl/gsl_randist.h>
24#include <gsl/gsl_permutation.h>
25#include <lal/LALHashTbl.h>
26
27typedef struct {
28 int key;
29 int value;
30} elem;
31
32static void *new_elem( int key, int value )
33{
34 elem e = { .key = key, .value = value };
35 return memcpy( XLALMalloc( sizeof( e ) ), &e, sizeof( e ) );
36}
37
38static UINT8 hash_elem( const void *x )
39{
40 const elem *ex = ( const elem * ) x;
41 UINT2 hval = 0;
42 XLALPearsonHash( &hval, sizeof( hval ), &ex->key, sizeof( ex->key ) );
43 return hval;
44}
45
46static int cmp_elem( const void *x, const void *y )
47{
48 const elem *ex = ( const elem * ) x;
49 const elem *ey = ( const elem * ) y;
50 return ex->key - ey->key;
51}
52
53int main( void )
54{
55
56 /* Create hash table */
57 LALHashTbl *ht = XLALHashTblCreate( XLALFree, hash_elem, cmp_elem );
58 XLAL_CHECK_MAIN( ht != NULL, XLAL_EFUNC );
60
61 /* Repeat hash table test a few times */
62 gsl_rng *r = gsl_rng_alloc( gsl_rng_mt19937 );
63 int clear_tested = 0;
64 for ( int n = 0; n < 4; ++n ) {
65
66 /* Add 100 elements with keys in 100*n + [0,99] to table in a random order */
67 {
68 XLAL_CHECK_MAIN( r != NULL, XLAL_ESYS );
69 gsl_permutation *p = gsl_permutation_calloc( 100 );
70 XLAL_CHECK_MAIN( p != NULL, XLAL_ESYS );
71 gsl_ran_shuffle( r, p->data, 100, sizeof( size_t ) );
72 for ( int i = 0; i < 100; ++i ) {
73 int key = 100*n + gsl_permutation_get( p, i );
74 XLAL_CHECK_MAIN( XLALHashTblAdd( ht, new_elem( key, 3*key - n ) ) == XLAL_SUCCESS, XLAL_EFUNC );
75 XLAL_CHECK_MAIN( XLALHashTblSize( ht ) == 100*n + i + 1, XLAL_EFAILED );
76 }
77 gsl_permutation_free( p );
78 }
79
80 /* Try finding all 100 elements by key */
81 for ( int i = 0; i < 100; ++i ) {
82 elem x = { .key = 100*n + i };
83 const elem *y;
84 XLAL_CHECK_MAIN( XLALHashTblFind( ht, &x, ( const void ** ) &y ) == XLAL_SUCCESS, XLAL_EFUNC );
85 XLAL_CHECK_MAIN( y != NULL, XLAL_EFAILED );
86 XLAL_CHECK_MAIN( y->value == 3*y->key - n, XLAL_EFAILED );
87 }
88
89 /* Try extracting all 100 elements, then adding them back */
90 for ( int i = 0; i < 100; ++i ) {
91 elem x = { .key = 100*n + i };
92 elem *y;
93 XLAL_CHECK_MAIN( XLALHashTblExtract( ht, &x, ( void ** ) &y ) == XLAL_SUCCESS, XLAL_EFUNC );
94 XLAL_CHECK_MAIN( y != NULL, XLAL_EFAILED );
95 XLAL_CHECK_MAIN( y->value == 3*y->key - n, XLAL_EFAILED );
96 const elem *z;
97 XLAL_CHECK_MAIN( XLALHashTblFind( ht, &x, ( const void ** ) &z ) == XLAL_SUCCESS, XLAL_EFUNC );
98 XLAL_CHECK_MAIN( z == NULL, XLAL_EFAILED );
100 XLAL_CHECK_MAIN( XLALHashTblFind( ht, &x, ( const void ** ) &z ) == XLAL_SUCCESS, XLAL_EFUNC );
101 XLAL_CHECK_MAIN( z != NULL, XLAL_EFAILED );
102 XLAL_CHECK_MAIN( z->value == 3*z->key - n, XLAL_EFAILED );
103 }
104
105 /* Try clearing hash table */
106 if ( !clear_tested && n == 0 ) {
108 clear_tested = 1;
109 n = -1;
110 }
111
112 }
114
115 /* Try removing some elements */
116 for ( int i = 0; i < 250; ++i ) {
117 elem x = { .key = i };
119 XLAL_CHECK_MAIN( XLALHashTblSize( ht ) == 400 - i - 1, XLAL_EFAILED );
120 }
121
122 /* Try finding the rest of the elements */
123 for ( int i = 250; i < 400; ++i ) {
124 elem x = { .key = i };
125 const elem *y;
126 XLAL_CHECK_MAIN( XLALHashTblFind( ht, &x, ( const void ** ) &y ) == XLAL_SUCCESS, XLAL_EFUNC );
127 XLAL_CHECK_MAIN( y != NULL, XLAL_EFAILED );
128 XLAL_CHECK_MAIN( y->value == 3*y->key - ( i / 100 ), XLAL_EFAILED );
129 }
130
131 /* Cleanup */
132 gsl_rng_free( r );
133 XLALHashTblDestroy( ht );
134
135 /* Check for memory leaks */
137
138 return EXIT_SUCCESS;
139
140}
int main(void)
static void * new_elem(int key, int value)
static UINT8 hash_elem(const void *x)
static int cmp_elem(const void *x, const void *y)
void LALCheckMemoryLeaks(void)
Definition: LALMalloc.c:784
uint64_t UINT8
Eight-byte unsigned integer; on some platforms this is equivalent to unsigned long int instead.
uint16_t UINT2
Two-byte unsigned integer.
int XLALPearsonHash(void *hval, const size_t hval_len, const void *data, const size_t data_len)
Compute a arbitrary-sized Pearson hash value for the given arbitrary data.
int XLALHashTblFind(const LALHashTbl *ht, const void *x, const void **y)
Find the element matching x in a hash table; if found, return in *y
Definition: LALHashTbl.c:185
int XLALHashTblSize(const LALHashTbl *ht)
Return the size of a hash table.
Definition: LALHashTbl.c:177
int XLALHashTblAdd(LALHashTbl *ht, void *x)
Add an element to a hash table.
Definition: LALHashTbl.c:215
int XLALHashTblExtract(LALHashTbl *ht, const void *x, void **y)
Find the element matching x in a hash table; if found, remove it and return in *y
Definition: LALHashTbl.c:252
int XLALHashTblRemove(LALHashTbl *ht, const void *x)
Find the element matching x in a hash table; if found, remove and destroy it.
Definition: LALHashTbl.c:287
LALHashTbl * XLALHashTblCreate(LALHashTblDtorFcn dtor, LALHashTblHashFcn hash, LALHashTblCmpFcn cmp)
Create a hash table.
Definition: LALHashTbl.c:86
void XLALHashTblDestroy(LALHashTbl *ht)
Destroy a hash table and its elements.
Definition: LALHashTbl.c:129
int XLALHashTblClear(LALHashTbl *ht)
Clear a hash table.
Definition: LALHashTbl.c:148
#define XLALMalloc(n)
Definition: LALMalloc.h:44
#define XLALFree(p)
Definition: LALMalloc.h:47
static const INT4 r
Definition: Random.c:82
#define XLAL_CHECK_MAIN(assertion,...)
Macro to test an assertion and invoke a failure if it is not true in a C main() routine.
Definition: XLALError.h:885
@ XLAL_SUCCESS
Success return value (not an error number)
Definition: XLALError.h:401
@ XLAL_EFUNC
Internal function call failed bit: "or" this with existing error number.
Definition: XLALError.h:462
@ XLAL_ESYS
System error.
Definition: XLALError.h:442
@ XLAL_EFAILED
Generic failure.
Definition: XLALError.h:418
Definition: LALBitset.c:31
int value
UINT8 key
Definition: LALBitset.c:32
int key