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