46#define DEFAULT_KEY_COUNT 250
49#define DEFAULT_DURATION_SEC 10
52#define TEST_KEY_LENGTH 32
55#define RANDOM_STRING_ATTEMPTS 100
109 for (i = 0; i < count; i++) {
111 unsigned int attempts = 0;
163 const char *
a = *(
const char **)_a;
164 const char *
b = *(
const char **)_b;
207 struct timeval start;
208 unsigned int count = 0;
217 e->
command =
"performance test ao2_string_hash";
219 "Usage: performance test ao2_string_hash [<num_keys>] [<duration_sec>] [<buckets>]\n"
220 " Test the performance of ao2_container hash string key lookups.\n";
227 if (sscanf(
a->argv[3],
"%30d", &key_count) <= 0 || key_count <= 0) {
228 ast_cli(
a->fd,
"Invalid value for num_keys: '%s'\n",
a->argv[3]);
233 if (sscanf(
a->argv[4],
"%30d", &duration_sec) <= 0 || duration_sec <= 0) {
234 ast_cli(
a->fd,
"Invalid value for duration_sec: '%s'\n",
a->argv[4]);
239 if (sscanf(
a->argv[5],
"%30d", &buckets) <= 0 || buckets <= 0) {
240 ast_cli(
a->fd,
"Invalid value for buckets: '%s'\n",
a->argv[5]);
244 duration_ms = duration_sec * 1000;
251 ast_cli(
a->fd,
"Failed to generate random strings\n");
257 ast_cli(
a->fd,
"Failed to allocate ao2 container\n");
264 ast_cli(
a->fd,
"Failed to add string to container\n");
271 ast_cli(
a->fd,
"Beginning ao2_string_hash performance test (%d keys, %d seconds, buckets %d)\n",
272 key_count, duration_sec, buckets);
286 ast_cli(
a->fd,
"ao2_string_hash: %u lookups in %d seconds (%u lookups/sec)\n", count, duration_sec, count / duration_sec);
304 return strncmp(lhs, rhs, strlen(rhs));
306 return strcmp(lhs, rhs);
322 cmp = strncmp(lhs, rhs, strlen(rhs));
324 cmp = strcmp(lhs, rhs);
341 struct timeval start;
342 unsigned int count = 0;
350 e->
command =
"performance test ao2_string_rbtree";
352 "Usage: performance test ao2_string_rbtree [<num_keys>] [<duration_sec>]\n"
353 " Test the performance of ao2_container rbtree string key lookups.\n";
360 if (sscanf(
a->argv[3],
"%30d", &key_count) <= 0 || key_count <= 0) {
361 ast_cli(
a->fd,
"Invalid value for num_keys: '%s'\n",
a->argv[3]);
366 if (sscanf(
a->argv[4],
"%30d", &duration_sec) <= 0 || duration_sec <= 0) {
367 ast_cli(
a->fd,
"Invalid value for duration_sec: '%s'\n",
a->argv[4]);
371 duration_ms = duration_sec * 1000;
375 ast_cli(
a->fd,
"Failed to generate random strings\n");
381 ast_cli(
a->fd,
"Failed to allocate ao2 rbtree container\n");
391 ast_cli(
a->fd,
"Failed to allocate object for string\n");
401 ast_cli(
a->fd,
"Beginning ao2_string_rbtree performance test (%d keys, %d seconds)\n",
402 key_count, duration_sec);
416 ast_cli(
a->fd,
"ao2_string_rbtree: %u lookups in %d seconds (%u lookups/sec)\n", count, duration_sec, count / duration_sec);
435 struct timeval start;
436 unsigned int count = 0;
444 e->
command =
"performance test ao2_string_list";
446 "Usage: performance test ao2_string_list [<num_keys>] [<duration_sec>]\n"
447 " Test the performance of ao2_container list string key lookups.\n";
454 if (sscanf(
a->argv[3],
"%30d", &key_count) <= 0 || key_count <= 0) {
455 ast_cli(
a->fd,
"Invalid value for num_keys: '%s'\n",
a->argv[3]);
460 if (sscanf(
a->argv[4],
"%30d", &duration_sec) <= 0 || duration_sec <= 0) {
461 ast_cli(
a->fd,
"Invalid value for duration_sec: '%s'\n",
a->argv[4]);
465 duration_ms = duration_sec * 1000;
469 ast_cli(
a->fd,
"Failed to generate random strings\n");
475 ast_cli(
a->fd,
"Failed to allocate ao2 list container\n");
485 ast_cli(
a->fd,
"Failed to allocate object for string\n");
495 ast_cli(
a->fd,
"Beginning ao2_string_list performance test (%d keys, %d seconds)\n",
496 key_count, duration_sec);
510 ast_cli(
a->fd,
"ao2_string_list: %u lookups in %d seconds (%u lookups/sec)\n", count, duration_sec, count / duration_sec);
538 struct timeval start;
539 unsigned int count = 0;
548 e->
command =
"performance test hashtab_string";
550 "Usage: performance test hashtab_string [<num_keys>] [<duration_sec>] [<buckets>]\n"
551 " Test the performance of hashtab string lookups.\n";
558 if (sscanf(
a->argv[3],
"%30d", &key_count) <= 0 || key_count <= 0) {
559 ast_cli(
a->fd,
"Invalid value for num_keys: '%s'\n",
a->argv[3]);
564 if (sscanf(
a->argv[4],
"%30d", &duration_sec) <= 0 || duration_sec <= 0) {
565 ast_cli(
a->fd,
"Invalid value for duration_sec: '%s'\n",
a->argv[4]);
570 if (sscanf(
a->argv[5],
"%30d", &buckets) <= 0 || buckets <= 0) {
571 ast_cli(
a->fd,
"Invalid value for buckets: '%s'\n",
a->argv[5]);
575 duration_ms = duration_sec * 1000;
582 ast_cli(
a->fd,
"Failed to generate random strings\n");
588 ast_cli(
a->fd,
"Failed to allocate hashtab\n");
597 ast_cli(
a->fd,
"Failed to insert string into hashtab\n");
605 ast_cli(
a->fd,
"Beginning hashtab_string performance test (%d keys, %d seconds, buckets %d)\n",
606 key_count, duration_sec, buckets);
620 ast_cli(
a->fd,
"hashtab_string: %u lookups in %d seconds (%u lookups/sec)\n", count, duration_sec, count / duration_sec);
648 struct timeval start;
649 unsigned int count = 0;
657 e->
command =
"performance test list_string";
659 "Usage: performance test list_string [<num_keys>] [<duration_sec>]\n"
660 " Test the performance of linked list string key lookups.\n";
667 if (sscanf(
a->argv[3],
"%30d", &key_count) <= 0 || key_count <= 0) {
668 ast_cli(
a->fd,
"Invalid value for num_keys: '%s'\n",
a->argv[3]);
673 if (sscanf(
a->argv[4],
"%30d", &duration_sec) <= 0 || duration_sec <= 0) {
674 ast_cli(
a->fd,
"Invalid value for duration_sec: '%s'\n",
a->argv[4]);
678 duration_ms = duration_sec * 1000;
682 ast_cli(
a->fd,
"Failed to generate random strings\n");
691 ast_cli(
a->fd,
"Failed to allocate list node\n");
698 ast_cli(
a->fd,
"Failed to duplicate list node string\n");
705 ast_cli(
a->fd,
"Beginning list_string performance test (%d keys, %d seconds)\n",
706 key_count, duration_sec);
724 ast_cli(
a->fd,
"list_string: %u lookups in %d seconds (%u lookups/sec)\n", count, duration_sec, count / duration_sec);
748 struct timeval start;
749 unsigned int count = 0;
757 e->
command =
"performance test vector_string_bsearch";
759 "Usage: performance test vector_string_bsearch [<num_keys>] [<duration_sec>]\n"
760 " Test the performance of vector string key binary search lookups.\n";
767 if (sscanf(
a->argv[3],
"%30d", &key_count) <= 0 || key_count <= 0) {
768 ast_cli(
a->fd,
"Invalid value for num_keys: '%s'\n",
a->argv[3]);
773 if (sscanf(
a->argv[4],
"%30d", &duration_sec) <= 0 || duration_sec <= 0) {
774 ast_cli(
a->fd,
"Invalid value for duration_sec: '%s'\n",
a->argv[4]);
778 duration_ms = duration_sec * 1000;
782 ast_cli(
a->fd,
"Failed to generate random strings\n");
787 ast_cli(
a->fd,
"Failed to initialize vector\n");
796 ast_cli(
a->fd,
"Failed to add string to vector\n");
809 ast_cli(
a->fd,
"Beginning vector_string_bsearch performance test (%d keys, %d seconds)\n",
810 key_count, duration_sec);
832 ast_cli(
a->fd,
"vector_string_bsearch: %u lookups in %d seconds (%u lookups/sec)\n", count, duration_sec, count / duration_sec);
852 struct timeval start;
853 unsigned int count = 0;
862 e->
command =
"performance test vector_string_linear";
864 "Usage: performance test vector_string_linear [<num_keys>] [<duration_sec>]\n"
865 " Test the performance of vector string linear search lookups.\n";
872 if (sscanf(
a->argv[3],
"%30d", &key_count) <= 0 || key_count <= 0) {
873 ast_cli(
a->fd,
"Invalid value for num_keys: '%s'\n",
a->argv[3]);
878 if (sscanf(
a->argv[4],
"%30d", &duration_sec) <= 0 || duration_sec <= 0) {
879 ast_cli(
a->fd,
"Invalid value for duration_sec: '%s'\n",
a->argv[4]);
883 duration_ms = duration_sec * 1000;
887 ast_cli(
a->fd,
"Failed to generate random strings\n");
892 ast_cli(
a->fd,
"Failed to initialize vector\n");
901 ast_cli(
a->fd,
"Failed to add string to vector\n");
912 ast_cli(
a->fd,
"Beginning vector_string_linear performance test (%d keys, %d seconds)\n",
913 key_count, duration_sec);
932 ast_cli(
a->fd,
"vector_string_linear: %u lookups in %d seconds (%u lookups/sec)\n", count, duration_sec, count / duration_sec);
952 e->
command =
"performance test container_key_lookup_all";
954 "Usage: performance test container_key_lookup_all [<num_keys>] [<duration_sec>] [<buckets>]\n"
955 " Run all performance tests.\n";
void ast_cli_unregister_multiple(void)
Asterisk main include file. File version handling, generic pbx functions.
#define ast_strdup(str)
A wrapper for strdup()
#define ast_calloc(num, len)
A wrapper for calloc()
#define ast_malloc(len)
A wrapper for malloc()
#define ao2_link(container, obj)
Add an object to a container.
@ AO2_ALLOC_OPT_LOCK_NOLOCK
#define ao2_find(container, arg, flags)
#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a red-black tree container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_alloc_options(data_size, destructor_fn, options)
@ OBJ_SEARCH_PARTIAL_KEY
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
@ OBJ_SEARCH_MASK
Search option field mask.
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Standard Command Line Interface.
#define AST_CLI_DEFINE(fn, txt,...)
void ast_cli(int fd, const char *fmt,...)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Generic (perhaps overly so) hashtable implementation Hash Table support in Asterisk.
void ast_hashtab_destroy(struct ast_hashtab *tab, void(*objdestroyfunc)(void *obj))
This func will free the hash table and all its memory.
int ast_is_prime(int num)
Determines if the specified number is prime.
int ast_hashtab_compare_strings(const void *a, const void *b)
Compares two strings for equality.
#define ast_hashtab_insert_immediate(tab, obj)
Insert without checking.
void * ast_hashtab_lookup(struct ast_hashtab *tab, const void *obj)
Lookup this object in the hash table.
#define ast_hashtab_create(initial_buckets, compare, resize, newsize, hash, do_locking)
Create the hashtable list.
unsigned int ast_hashtab_hash_string(const void *obj)
Hashes a string to a number.
A set of macros to manage forward-linked lists.
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Asterisk module definitions.
#define AST_MODULE_INFO_STANDARD(keystr, desc)
#define ASTERISK_GPL_KEY
The text the key() function should return.
@ AST_MODULE_LOAD_SUCCESS
struct ao2_container * container
static void cleanup(void)
Clean up any old apps that we don't need any more.
String manipulation functions.
char * ast_generate_random_string(char *buf, size_t size)
Create a pseudo-random string of a fixed length.
struct ao2_container * ast_str_container_alloc_options(enum ao2_alloc_opts opts, int buckets)
Allocates a hash container for bare strings.
int ast_str_container_add(struct ao2_container *str_container, const char *add)
Adds a string to a string container allocated by ast_str_container_alloc.
descriptor for a cli entry.
String vector definitions.
A node in the linked list for string lookups.
struct list_node::@545 list
Time-related functions and macros.
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
long int ast_random(void)
Vector container support.
#define AST_VECTOR_RESET(vec, cleanup)
Reset vector.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
#define AST_VECTOR_BSEARCH(vec, key, cmp)
Binary search a sorted vector.
#define AST_VECTOR_SORT(vec, cmp)
Sort a vector in-place.
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.