err_t _deque_reallocate_map(const ssize_t item_size, const ssize_t buf_size, deque_t* d, ssize_t nodes_to_add, char add_at_front) { const ssize_t old_num_nodes = d->finish.node - d->start.node + 1; const ssize_t new_num_nodes = old_num_nodes + nodes_to_add; deque_node_t* new_nstart; if( d->map_size > 2 * new_num_nodes ) { new_nstart = d->map + (d->map_size - new_num_nodes) / 2 + (add_at_front ? nodes_to_add : 0 ); if( new_nstart < d->start.node ) { // copy from d->start.node to d->finish.node + 1 to new_nstart _deque_map_copy_forward(d->start.node, d->finish.node + 1, new_nstart); } else { // copy backward from d->start.node to d->finish.node + 1 to new_nstart + old_num_nodes elements _deque_map_copy_backward(d->start.node, d->finish.node + 1, new_nstart + old_num_nodes); } } else { ssize_t new_map_size = d->map_size + _DEQUE_MAX(d->map_size, nodes_to_add) + 2; deque_node_t* new_map = (deque_node_t*) deque_calloc(new_map_size, sizeof(deque_node_t)); if( ! new_map ) return ENOMEM; new_nstart = new_map + (new_map_size - new_num_nodes ) / 2 + (add_at_front ? nodes_to_add : 0 ); // copy from d->start.node to d->finish.node + 1 to new_nstart _deque_map_copy_forward(d->start.node, d->finish.node + 1, new_nstart); deque_free(d->map); d->map = new_map; d->map_size = new_map_size; } _deque_set_node(item_size, buf_size, & d->start, new_nstart); _deque_set_node(item_size, buf_size, & d->finish, new_nstart + old_num_nodes - 1); return 0; }
void simple_test( void){ deque dq; double a; int i, status; fprintf( stdout, "Testing deque_allocate: " ); dq = deque_alloc(); if( dq != NULL ){ fprintf( stdout, "success!\n"); }else{ fprintf( stdout, "failed!\n"); } fprintf( stdout, "Testing deque_empty: "); if( deque_empty( dq) ){ fprintf( stdout, "success!\n"); }else{ fprintf( stdout, "failed!\n"); } a = 2.5; fprintf( stdout, "Testing deque_push_back, value=%1.2g: ", a); if( deque_push_back( dq, a ) == DEQUE_SUCCESS ){ fprintf( stdout, "success!\n"); }else{ fprintf( stdout, "failed!\n"); } a = 3.14159; fprintf( stdout, "Testing deque_peek_back: "); if( deque_peek_back( dq, &a) == DEQUE_SUCCESS ){ fprintf( stdout, "success!, value=%1.2g\n", a); }else{ fprintf( stdout, "failed, value=%1.2g\n", a); } fprintf( stdout, "Testing deque_size: "); fprintf( stdout, "size=%d\n", deque_size( dq)); fprintf( stdout, "Testing deque_pop_back: "); a = 3.14159; if( deque_pop_back( dq, &a) == DEQUE_SUCCESS ){ fprintf( stdout, "success!, value=%1.2g\n", a); }else{ fprintf( stdout, "failed!, value=%1.2g\n", a); } a = 3.14159; fprintf( stdout, "Testing deque_pop_back on empty deque: "); if( deque_pop_back( dq, &a) != DEQUE_EMPTY ){ fprintf( stdout, "failed!, value=%1.2g\n", a); }else{ fprintf( stdout, "success!,\n"); fprintf( stdout, " caught empty deque, value=%1.2g\n", a); } a = 2.5; fprintf( stdout, "Testing deque_push_front, value=%1.2g: ", a); if( deque_push_front( dq, a ) == DEQUE_SUCCESS ){ fprintf( stdout, "success!\n"); }else{ fprintf( stdout, "failed!\n"); } a = 3.14159; fprintf( stdout, "Testing deque_peek_front: "); if( deque_peek_front( dq, &a) == DEQUE_SUCCESS ){ fprintf( stdout, "success!, value=%1.2g\n", a); }else{ fprintf( stdout, "failed, value=%1.2g\n", a); } fprintf( stdout, "Testing deque_size: "); fprintf( stdout, "size=%d\n", deque_size( dq)); fprintf( stdout, "Testing deque_pop_front: "); a = 3.14159; if( deque_pop_front( dq, &a) == DEQUE_SUCCESS ){ fprintf( stdout, "success!, value=%1.2g\n", a); }else{ fprintf( stdout, "failed!, value=%1.2g\n", a); } a = 3.14159; fprintf( stdout, "Testing deque_pop_front on empty deque: "); if( deque_pop_front( dq, &a) != DEQUE_EMPTY ){ fprintf( stdout, "failed!, value=%1.2g\n", a); }else{ fprintf( stdout, "success!,\n"); fprintf( stdout, " caught empty deque, value=%1.2g\n", a); } fprintf( stdout, "Testing deque_get_item: "); for( i=0; i<5; i++ ){ a = (double) i + 0.545; if( deque_push_back( dq, a) != DEQUE_SUCCESS ){ fprintf( stderr, "deque push back failed!\n" ); deque_free( dq); return; } a = (-1. - (double) i) + 0.545; if( deque_push_front( dq, a) != DEQUE_SUCCESS ){ fprintf( stderr, "deque push front failed!\n" ); deque_free( dq); return; } } for( i=0; i<10; i++){ status = deque_get_item( dq, i, &a); if( status != DEQUE_SUCCESS || a != (-5. + (double) i) + 0.545 ){ fprintf( stderr, "deque get_item failed!\n" ); deque_free( dq); return; } } a = 3.14159; status = deque_get_item( dq, 11, &a); if( status != DEQUE_OUT_OF_BOUNDS || a != 3.14159 ){ fprintf( stderr, "deque get_item out of bounds failed!\n"); deque_free( dq); } fprintf( stdout, "success!\n"); deque_free( dq); }
void big_test( int num){ int center, front, back, i, sw, status, fsize; double *vals, *pvals, tmp; clock_t start, stop, diff; int msecs; deque dq; dq = deque_alloc(); vals = (double *) malloc( 2*num*sizeof(double)); pvals = (double *) malloc( 2*num*sizeof(double)); for( i=0; i<2*num; i++){ vals[i] = (double) rand() / (double) RAND_MAX; } front = 0; back = 0; center = num; fprintf( stdout, "Testing deque_push_back and front %d times\n", num/2); start = clock(); for( i=0; i<num/2; i++){ if( rand() % 2 == 0 ){ deque_push_back( dq, vals[center+back] ); back++; }else{ front--; deque_push_front( dq, vals[center+front] ); } } stop = clock(); diff = stop-start; msecs = (int) diff * 1000 / CLOCKS_PER_SEC; fprintf( stdout, " succeeded in %u ms\n", msecs); fprintf( stdout, "Testing deque_push(pop)_back(front) %d times\n", num); start = clock(); for( i=0; i<num; i++){ sw = rand() % 4; switch( sw ){ case 0: status = deque_push_back( dq, vals[center+back]); back++; break; case 1: front--; status = deque_push_front( dq, vals[center+front]); break; case 2: back--; status = deque_pop_back( dq, &tmp); break; case 3: status = deque_pop_front( dq, &tmp); front++; break; default: status = 1; tmp = 1; } if( status != DEQUE_SUCCESS ){ fprintf( stderr, " error at op i=%d\n", i); free( pvals); free( vals); deque_free( dq); return; } } stop = clock(); diff = stop-start; msecs = (int) diff * 1000 / CLOCKS_PER_SEC; fprintf( stdout, " succeeded in %u ms\n", msecs); fsize = deque_size( dq); fprintf( stdout, "Testing deque_get_item %d times\n", fsize); start = clock(); for( i=0; i<fsize; i++){ deque_get_item( dq, i, &(pvals[i])); } stop = clock(); for( i=0; i<fsize; i++){ if( pvals[i] != vals[center+front+i] ){ fprintf( stderr, " obtained value error! at item %d\n", i); free( pvals); free( vals); deque_free( dq); return; } } diff = stop-start; msecs = (int) diff * 1000 / CLOCKS_PER_SEC; fprintf( stdout, " succeeded in %u ms\n", msecs); fprintf( stdout, "Testing deque_pop_front %d times\n", fsize); start = clock(); for( i=0; i<fsize; i++){ deque_pop_front( dq, &(pvals[i])); } stop = clock(); for( i=0; i<fsize; i++){ if( pvals[i] != vals[center+front+i] ){ fprintf( stderr, " obtained value error! at item %d\n", i); free( pvals); free( vals); deque_free( dq); return; } } diff = stop-start; msecs = (int) diff * 1000 / CLOCKS_PER_SEC; fprintf( stdout, " succeeded in %u ms\n", msecs); free( pvals); free( vals); deque_free( dq); }
int main() { { deque_t d = new_deque(); SPAN(tuple_ix_t) span = deque_as_span(&d); assert(span.ptr == NULL); assert(span.sz == 0); deque_free(&d); } { deque_t d = new_deque(); deque_push_back(&d, 1234); SPAN(tuple_ix_t) span = deque_as_span(&d); assert(span.ptr != NULL); assert(span.sz == 1); assert(span.ptr[0] == 1234); deque_free(&d); free(span.ptr); } { deque_t d = new_deque(); enum {NREP = 40000}; size_t ix = 0; for (ix = 0; ix < NREP; ++ix) { deque_push_back(&d, ix + 1234); } SPAN(tuple_ix_t) span = deque_as_span(&d); assert(span.ptr != NULL); assert(span.sz == NREP); for (ix = 0; ix < NREP; ++ix) { assert(span.ptr[ix] == (ix + 1234)); } deque_free(&d); free(span.ptr); } { deque_t d = new_deque(); enum {NREP = 40000000}; size_t ix = 0; for (ix = 0; ix < NREP; ++ix) { deque_push_back(&d, ix + 1234); } SPAN(tuple_ix_t) span = deque_as_span(&d); assert(span.ptr != NULL); assert(span.sz == NREP); for (ix = 0; ix < NREP; ++ix) { assert(span.ptr[ix] == (ix + 1234)); } deque_free(&d); free(span.ptr); } return 0; }