debugging" vector" and added regression test
[rrq/rrqmisc.git] / tests / vectortests.c
1 /**
2  * A sequence of tests of the vector.h functions.
3  */
4
5 #include <stdio.h>
6 #include <string.h>
7 #include <vector.h>
8
9 #define OUT(...) fprintf( stderr, __VA_ARGS__ )
10
11 // dump an item; return 0 to stop
12 static void itemdump(const vector_index index,const void *slot) {
13     if ( slot ) {
14         OUT ( "[%ld] %s\n", index, (const char*) slot );
15     }
16 }
17
18 // pretend-reclaim item and return data (as int)
19 static int itemreclaim(vector *pv,vector_index index,void *item,void *data) {
20     int r = data? 1 : 0;
21     OUT( "reclaim [%ld] (%p) => %d\n", index, item, r );
22     return r;
23 }
24
25 // Compare two items strings, or nulls
26 static int itemcmp(const void *a,const void *b) {
27     return a? ( b? strcmp( (char*)b, (char*)a ) : 1 ) : ( b? -1 : 0 );
28 }
29
30 // Iterator function
31 static int itemiter(vector_index index,void *item,void *data) {
32     char *s = "";
33     if ( item ) {
34         s = (char*) item;
35     }
36     OUT( "[%ld] %p %s\n", index, item, s );
37     return ( index < 12 ) == 0;
38 }
39
40 // check if item before, at or after the key
41 int itemfind(const void *key, const void *item) {
42     char *a = (char*) key;
43     size_t an = a? strlen( a ) : 0;
44     char *b = (char*) item;
45     size_t bn = b? strlen( b ) : 0;
46     OUT( "itemfind %p \"%s\" %p \"%s\"\n",
47          a, a? a : "(null)", b, b? b : "(null)" );
48     return strncmp( a, b, (an<bn)? an : bn );
49 }
50
51 // Dump a vector with a header line
52 static void my_vector_dump(
53     vector *vp,
54     void (*itemdump)(const vector_index index,const void *slot) )
55 {
56     OUT( "vector %p has %ld slots\n", vp, vector_size(vp) );
57     vector_dump( vp, itemdump );
58 }
59
60 int main(int argc,char **argv) {
61     OUT( "VECTOR_LEVEL_BITS = %d\n", VECTOR_LEVEL_BITS );
62     OUT( "sizeof( vector_index ) = %ld\n", sizeof( vector_index ) );
63     OUT( "VECTOR_INDEX_BITS - %ld\n", VECTOR_INDEX_BITS );
64     OUT( "VECTOR_INDEX_FIELDS = %ld\n", VECTOR_INDEX_FIELDS );
65     OUT( "VECTOR_SLOTS = %d\n", VECTOR_SLOTS );
66     OUT( "sizeof( vector_page ) = %ld\n", sizeof( vector_page ) );
67     OUT( "sizeof( vector ) = %ld\n", sizeof( vector ) );
68
69     vector v = { 100, 0 }; // Create an empty vector of 100 slots.
70     void ** slot;
71     void *item;
72     int i;
73     
74     OUT( "vector v has 100 empty slots\n" );
75
76     // void vector_dump(vector *pv,
77     //    int (*itemdump)(const vector_index ,const void *));
78     // void **vector_next_used(vector *pv,vector_index *index);
79     my_vector_dump( &v, itemdump );
80
81     //void vector_set(vector *pv,vector_index index,void *value);
82     vector_set( &v, 25, "this is first item" );
83
84     // void **vector_prev_used(vector *pv,vector_index *index);
85     int t0[6] = { 0, 25, 50, 99, 100, 1000 };
86     OUT( "vector_next_used:\n" );
87     for ( i = 0; i < 6; i++ ) {
88         vector_index index = t0[i];
89         slot = vector_next_used( &v, &index );
90         OUT( " [%d] => [%ld] %p\n", t0[i], index, slot );
91     }
92
93     OUT( "vector_prev_used:\n" );
94     for ( i = 0; i < 6; i++ ) {
95         vector_index index = t0[i];
96         slot = vector_prev_used( &v, &index );
97         OUT( " [%d] => [%ld] %p\n", t0[i], index, slot );
98     }
99
100     vector_set( &v, 75, "this is second item" );
101     OUT( "vector v has 2 non-empty slots\n" );
102     my_vector_dump( &v, itemdump );
103     
104     OUT( "vector_next_used:\n" );
105     for ( i = 0; i < 6; i++ ) {
106         vector_index index = t0[i];
107         slot = vector_next_used( &v, &index );
108         OUT( " [%d] => [%ld] %p\n", t0[i], index, slot );
109     }
110
111     OUT( "vector_prev_used:\n" );
112     for ( i = 0; i < 6; i++ ) {
113         vector_index index = t0[i];
114         slot = vector_prev_used( &v, &index );
115         OUT( " [%d] => [%ld] %p\n", t0[i], index, slot );
116     }
117
118     OUT( "shrinking the vector:\n" );
119     // int vector_resize(
120     //     vector *pv, vector_index new_size,
121     //     int (*reclaim)(vector *pv,vector_index index,void *item,void *data),
122     //     void *data );
123     i = vector_resize( &v, 50, itemreclaim, (void*)1 );
124     OUT( "shrink to 50 (reclaim refused) = %d\n", i );
125          
126
127     i = vector_resize( &v, 50, itemreclaim, (void*)0 );
128     OUT( "shrink to 50 (accept reclaim) = %d\n", i );
129
130     i = vector_resize( &v, 508, 0, 0 );
131     OUT( "grow to 508 (no reclaim) = %d\n", i );
132
133     // void **vector_entry(vector *pv,vector_index index); 
134 #define SLOTSTR(slot) (slot? ((*slot)? *slot : "(nil)") : "(unassigned)" )
135     slot = vector_entry( &v, 24 );
136     itemdump( 24, SLOTSTR(slot) );
137
138     slot = vector_entry( &v, 25 );
139     itemdump( 25, SLOTSTR(slot) );
140
141     slot = vector_entry( &v, 300 );
142     itemdump( 300, SLOTSTR( slot ) );
143
144     //#define vector_size(pv) ((vector_index) (pv)->size)
145     OUT( "vector size: %ld\n", vector_size( &v ) );
146
147     // void *vector_get_set(vector *pv,vector_index index,void *value);
148     item = vector_get_set( &v, 25, "another value" );
149     // void *vector_get(vector *pv,vector_index index);
150     OUT( "old: \"%s\", new: \"%s\"\n",
151          (char*)item, (char*)vector_get( &v, 25 ) );
152
153     // void vector_append(vector *pv,void *value);
154     vector_append( &v, "the very last item" );
155     OUT( "vector size: %ld\n", vector_size( &v ) );
156     my_vector_dump( &v, itemdump );
157
158     vector v2 = { 200, 0 };
159     // void vector_copy(
160     //        vector *dst,vector_index di,
161     //        vector *src,vector_index si,
162     //        vector_index n);
163     vector_copy( &v2, 20, &v, 10, 20 );
164     my_vector_dump( &v2, itemdump );
165
166     vector_resize( &v2, 0, itemreclaim, 0 ); // Reset vector v2
167     my_vector_dump( &v2, itemdump );
168
169     vector_append( &v2, "9 the very last item" );
170     vector_append( &v2, "3 the very last item" );
171     vector_append( &v2, "4 the very last item" );
172     vector_append( &v2, "6 the very last item" );
173     vector_append( &v2, "5 the very last item" );
174     vector_resize( &v2, vector_size( &v2 ) + 3, 0, 0 );
175     vector_append( &v2, "2 the very last item" );
176     vector_append( &v2, "8 the very last item" );
177     vector_append( &v2, "1 the very last item" );
178     vector_append( &v2, 0 );
179     vector_append( &v2, "7 the very last item" );
180     vector_append( &v2, "0 the very last item" );
181     my_vector_dump( &v2, itemdump );
182
183     // void vector_qsort(vector *pv,int (*compar)(const void *,const void *));
184     OUT( "sorted:" );
185     vector_qsort( &v2, itemcmp );
186     my_vector_dump( &v2, itemdump );
187
188     // void vector_iterate(vector *pv,
189     //      vector_index start,
190     //      int (*itemfn)(vector_index,void *item,void *data),
191     //      void *data);
192     OUT( "showing all slots\n" );
193     vector_iterate( &v2, 4, itemiter, 0 );
194
195     // void *vector_bsearch(vector *pv,vector_index *index,const void *key,
196     //       int (*compare)(const void *key, const void *item));
197     char *pfx[5] = { "4", "9", "0", "3", "10" };
198     for ( i = 0; i < ( sizeof( pfx ) / sizeof( char* ) ); i++ ) {
199         char *prefix = pfx[i];
200         vector_index index = 0;
201         OUT( "lookup prefix \"%s\":\n", prefix );
202         item = vector_bsearch( &v2, &index, prefix, itemfind );
203         OUT( "[%ld] %p %s\n", index, item, ( item? (char*)item : "(null)" ) );
204     }
205
206     return 0;
207 }