2013-03-21 05:42:28 +04:00
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd .
Copyright 2013 Lennart Poettering
systemd is free software ; you can redistribute it and / or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation ; either version 2.1 of the License , or
( at your option ) any later version .
systemd is distributed in the hope that it will be useful , but
WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
Lesser General Public License for more details .
You should have received a copy of the GNU Lesser General Public License
along with systemd ; If not , see < http : //www.gnu.org/licenses/>.
* * */
# include <stdlib.h>
# include "util.h"
# include "set.h"
# include "prioq.h"
2013-12-22 22:59:12 +04:00
# include "siphash24.h"
2013-03-21 05:42:28 +04:00
# define SET_SIZE 1024*4
static int unsigned_compare ( const void * a , const void * b ) {
const unsigned * x = a , * y = b ;
if ( * x < * y )
return - 1 ;
if ( * x > * y )
return 1 ;
return 0 ;
}
static void test_unsigned ( void ) {
unsigned buffer [ SET_SIZE ] , i ;
Prioq * q ;
srand ( 0 ) ;
q = prioq_new ( trivial_compare_func ) ;
assert_se ( q ) ;
for ( i = 0 ; i < ELEMENTSOF ( buffer ) ; i + + ) {
unsigned u ;
u = ( unsigned ) rand ( ) ;
buffer [ i ] = u ;
assert_se ( prioq_put ( q , UINT_TO_PTR ( u ) , NULL ) > = 0 ) ;
}
qsort ( buffer , ELEMENTSOF ( buffer ) , sizeof ( buffer [ 0 ] ) , unsigned_compare ) ;
for ( i = 0 ; i < ELEMENTSOF ( buffer ) ; i + + ) {
unsigned u ;
assert_se ( prioq_size ( q ) = = ELEMENTSOF ( buffer ) - i ) ;
u = PTR_TO_UINT ( prioq_pop ( q ) ) ;
assert_se ( buffer [ i ] = = u ) ;
}
assert_se ( prioq_isempty ( q ) ) ;
prioq_free ( q ) ;
}
struct test {
unsigned value ;
unsigned idx ;
} ;
static int test_compare ( const void * a , const void * b ) {
const struct test * x = a , * y = b ;
if ( x - > value < y - > value )
return - 1 ;
if ( x - > value > y - > value )
return 1 ;
return 0 ;
}
2013-12-22 22:59:12 +04:00
static unsigned long test_hash ( const void * a , const uint8_t hash_key [ HASH_KEY_SIZE ] ) {
2013-03-21 05:42:28 +04:00
const struct test * x = a ;
2013-12-22 22:59:12 +04:00
uint64_t u ;
2013-03-21 05:42:28 +04:00
2013-12-22 22:59:12 +04:00
siphash24 ( ( uint8_t * ) & u , & x - > value , sizeof ( x - > value ) , hash_key ) ;
return ( unsigned long ) u ;
2013-03-21 05:42:28 +04:00
}
2014-08-13 03:00:18 +04:00
static const struct hash_ops test_hash_ops = {
. hash = test_hash ,
. compare = test_compare
} ;
2013-03-21 05:42:28 +04:00
static void test_struct ( void ) {
Prioq * q ;
Set * s ;
unsigned previous = 0 , i ;
int r ;
srand ( 0 ) ;
q = prioq_new ( test_compare ) ;
assert_se ( q ) ;
2014-08-13 03:00:18 +04:00
s = set_new ( & test_hash_ops ) ;
2013-03-21 05:42:28 +04:00
assert_se ( s ) ;
for ( i = 0 ; i < SET_SIZE ; i + + ) {
struct test * t ;
t = new0 ( struct test , 1 ) ;
assert_se ( t ) ;
t - > value = ( unsigned ) rand ( ) ;
r = prioq_put ( q , t , & t - > idx ) ;
assert_se ( r > = 0 ) ;
if ( i % 4 = = 0 ) {
2013-04-23 07:12:15 +04:00
r = set_consume ( s , t ) ;
2013-03-21 05:42:28 +04:00
assert_se ( r > = 0 ) ;
}
}
for ( ; ; ) {
struct test * t ;
t = set_steal_first ( s ) ;
if ( ! t )
break ;
r = prioq_remove ( q , t , & t - > idx ) ;
assert_se ( r > 0 ) ;
free ( t ) ;
}
for ( i = 0 ; i < SET_SIZE * 3 / 4 ; i + + ) {
struct test * t ;
assert_se ( prioq_size ( q ) = = ( SET_SIZE * 3 / 4 ) - i ) ;
t = prioq_pop ( q ) ;
assert_se ( t ) ;
assert_se ( previous < = t - > value ) ;
previous = t - > value ;
free ( t ) ;
}
assert_se ( prioq_isempty ( q ) ) ;
prioq_free ( q ) ;
assert_se ( set_isempty ( s ) ) ;
set_free ( s ) ;
}
int main ( int argc , char * argv [ ] ) {
test_unsigned ( ) ;
test_struct ( ) ;
return 0 ;
}