Asterisk - The Open Source Telephony Project GIT-master-5467495
Loading...
Searching...
No Matches
Data Structures | Macros | Functions | Variables
test_performance.c File Reference

Performance Experimentation Tests. More...

#include "asterisk.h"
#include "asterisk/module.h"
#include "asterisk/cli.h"
#include "asterisk/time.h"
#include "asterisk/astobj2.h"
#include "asterisk/vector.h"
#include "asterisk/utils.h"
#include "asterisk/strings.h"
#include "asterisk/hashtab.h"
#include "asterisk/linkedlists.h"
#include <stdlib.h>
Include dependency graph for test_performance.c:

Go to the source code of this file.

Data Structures

struct  list_node
 A node in the linked list for string lookups. More...
 

Macros

#define DEFAULT_DURATION_SEC   10
 The default duration of the performance test in seconds.
 
#define DEFAULT_KEY_COUNT   250
 The default number of keys to generate for performance tests.
 
#define RANDOM_STRING_ATTEMPTS   100
 The number of attempts for random strings before we give up.
 
#define TEST_KEY_LENGTH   32
 The length of each test key.
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static void free_random_strings (struct ast_vector_string *vec)
 Frees the memory used by a vector of random strings.
 
static struct ast_vector_stringgenerate_random_strings (int count)
 Generates a vector of random strings to use as keys.
 
static char * handle_cli_ao2_string_hash (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Handles the CLI command for testing ao2_container hash string lookups.
 
static char * handle_cli_ao2_string_list (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Handles the CLI command for testing ao2_container list string lookups.
 
static char * handle_cli_ao2_string_rbtree (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Handles the CLI command for testing ao2_container rbtree string lookups.
 
static char * handle_cli_container_key_lookup_all (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Handles the CLI command for running all container key lookup performance tests.
 
static char * handle_cli_hashtab_string (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Handles the CLI command for testing hashtab string lookups.
 
static char * handle_cli_list_string (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Handle the 'performance test list_string' command.
 
static char * handle_cli_vector_bsearch_lookup (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Handles the CLI command for testing vector string binary search lookups.
 
static char * handle_cli_vector_linear_lookup (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Handles the CLI command for testing vector string linear search lookups.
 
static void hashtab_free_string (void *obj)
 Frees a string object placed into a hashtab.
 
static int load_module (void)
 Loads the performance testing module.
 
static int next_prime (int n)
 Finds the next prime number greater than or equal to n.
 
static int rbtree_str_cmp (void *lhs, void *rhs, int flags)
 Compares two strings for finding in the RBTree.
 
static int rbtree_str_sort (const void *lhs, const void *rhs, int flags)
 Compares two strings for sorting in the RBTree.
 
static int unload_module (void)
 Unloads the performance testing module.
 
static int vector_string_cmp (const void *_a, const void *_b)
 Compares two strings for sorting.
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Performance Test Experimentation Module" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_cli_entry cli_performance []
 The CLI commands for performance experimentation testing.
 

Detailed Description

Performance Experimentation Tests.

Author
Joshua Colp jcolp.nosp@m.@san.nosp@m.goma..nosp@m.com

Definition in file test_performance.c.

Macro Definition Documentation

◆ DEFAULT_DURATION_SEC

#define DEFAULT_DURATION_SEC   10

The default duration of the performance test in seconds.

Definition at line 49 of file test_performance.c.

◆ DEFAULT_KEY_COUNT

#define DEFAULT_KEY_COUNT   250

The default number of keys to generate for performance tests.

Definition at line 46 of file test_performance.c.

◆ RANDOM_STRING_ATTEMPTS

#define RANDOM_STRING_ATTEMPTS   100

The number of attempts for random strings before we give up.

Definition at line 55 of file test_performance.c.

◆ TEST_KEY_LENGTH

#define TEST_KEY_LENGTH   32

The length of each test key.

Definition at line 52 of file test_performance.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1013 of file test_performance.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1013 of file test_performance.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 1013 of file test_performance.c.

◆ free_random_strings()

static void free_random_strings ( struct ast_vector_string vec)
static

Frees the memory used by a vector of random strings.

The following tests cover the most common usage of containers in Asterisk - a key lookup based on a string which then resolves to an underlying object. The CLI commands assume that the underlying container implementations are working properly and return the requested object. These tests also only test single threaded performance. They do not test concurrent access or thread safety.

Parameters
vecThe vector of random strings to free

Definition at line 69 of file test_performance.c.

70{
72 AST_VECTOR_FREE(vec);
73 ast_free(vec);
74}
#define ast_free(a)
Definition astmm.h:180
#define AST_VECTOR_RESET(vec, cleanup)
Reset vector.
Definition vector.h:653
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition vector.h:185

References ast_free, AST_VECTOR_FREE, and AST_VECTOR_RESET.

Referenced by generate_random_strings(), handle_cli_ao2_string_hash(), handle_cli_ao2_string_list(), handle_cli_ao2_string_rbtree(), handle_cli_hashtab_string(), handle_cli_list_string(), handle_cli_vector_bsearch_lookup(), and handle_cli_vector_linear_lookup().

◆ generate_random_strings()

static struct ast_vector_string * generate_random_strings ( int  count)
static

Generates a vector of random strings to use as keys.

Parameters
countThe number of strings to generate
Returns
A vector of random strings, or NULL on failure

Definition at line 81 of file test_performance.c.

82{
83 struct ast_vector_string *vec;
84 struct ao2_container *seen;
85 int i;
86
87 vec = ast_malloc(sizeof(*vec));
88 if (!vec) {
89 return NULL;
90 }
91
92 /* Preallocate the vector to avoid reallocations during insertion */
93 if (AST_VECTOR_INIT(vec, count)) {
94 ast_free(vec);
95 return NULL;
96 }
97
98 /*
99 * To eliminate collissions keep track of seen strings and retry if a collision occurs,
100 * since this is just for keeping track of seen we don't care about optimizing the bucket
101 * size of the container.
102 */
104 if (!seen) {
106 return NULL;
107 }
108
109 for (i = 0; i < count; i++) {
110 char buf[TEST_KEY_LENGTH];
111 unsigned int attempts = 0;
112 char *dup;
113
114 /* Generate a random string and retry if it collides with a previously seen string */
115 while (1) {
116 char *existing;
117
119
120 existing = ao2_find(seen, buf, OBJ_SEARCH_KEY);
121 /* We don't care about the existing string, just that it's not NULL */
122 ao2_cleanup(existing);
123 if (!existing) {
124 break;
125 }
126
127 /* To prevent infinite loops in case of collisions, limit the number of attempts */
128 attempts++;
129 if (attempts > RANDOM_STRING_ATTEMPTS) {
130 ao2_ref(seen, -1);
132 return NULL;
133 }
134 }
135
136 /* The vector takes pointers to strings, so we need to duplicate the buffer */
137 dup = ast_strdup(buf);
138 if (!dup) {
139 ao2_ref(seen, -1);
141 return NULL;
142 }
143
144 ast_str_container_add(seen, dup);
145
146 /* This can't fail as the AST_VECTOR_INIT ensured enough space */
147 AST_VECTOR_APPEND(vec, dup);
148 }
149
150 ao2_ref(seen, -1);
151
152 return vec;
153}
#define ast_strdup(str)
A wrapper for strdup()
Definition astmm.h:241
#define ast_malloc(len)
A wrapper for malloc()
Definition astmm.h:191
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition astobj2.h:367
#define ao2_cleanup(obj)
Definition astobj2.h:1934
#define ao2_find(container, arg, flags)
Definition astobj2.h:1736
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition astobj2.h:459
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition astobj2.h:1101
char buf[BUFSIZE]
Definition eagi_proxy.c:66
#define NULL
Definition resample.c:96
char * ast_generate_random_string(char *buf, size_t size)
Create a pseudo-random string of a fixed length.
Definition strings.c:226
struct ao2_container * ast_str_container_alloc_options(enum ao2_alloc_opts opts, int buckets)
Allocates a hash container for bare strings.
Definition strings.c:200
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.
Definition strings.c:205
Generic container type.
String vector definitions.
Definition vector.h:55
#define RANDOM_STRING_ATTEMPTS
The number of attempts for random strings before we give up.
#define TEST_KEY_LENGTH
The length of each test key.
static void free_random_strings(struct ast_vector_string *vec)
Frees the memory used by a vector of random strings.
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition vector.h:124
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition vector.h:267

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_cleanup, ao2_find, ao2_ref, ast_free, ast_generate_random_string(), ast_malloc, ast_str_container_add(), ast_str_container_alloc_options(), ast_strdup, AST_VECTOR_APPEND, AST_VECTOR_INIT, buf, free_random_strings(), NULL, OBJ_SEARCH_KEY, RANDOM_STRING_ATTEMPTS, and TEST_KEY_LENGTH.

Referenced by handle_cli_ao2_string_hash(), handle_cli_ao2_string_list(), handle_cli_ao2_string_rbtree(), handle_cli_hashtab_string(), handle_cli_list_string(), handle_cli_vector_bsearch_lookup(), and handle_cli_vector_linear_lookup().

◆ handle_cli_ao2_string_hash()

static char * handle_cli_ao2_string_hash ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Handles the CLI command for testing ao2_container hash string lookups.

Parameters
eThe CLI entry
cmdThe command to execute
aThe CLI arguments
Returns
NULL on success, or an error message on failure

Definition at line 203 of file test_performance.c.

204{
205 struct ao2_container *container;
206 struct ast_vector_string *strings;
207 struct timeval start;
208 unsigned int count = 0;
209 int key_count = DEFAULT_KEY_COUNT;
210 int duration_sec = DEFAULT_DURATION_SEC;
211 int duration_ms;
212 int buckets = 0;
213 int i;
214
215 switch (cmd) {
216 case CLI_INIT:
217 e->command = "performance test ao2_string_hash";
218 e->usage =
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";
221 return NULL;
222 case CLI_GENERATE:
223 return NULL;
224 }
225
226 if (a->argc > 3) {
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]);
229 return CLI_FAILURE;
230 }
231 }
232 if (a->argc > 4) {
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]);
235 return CLI_FAILURE;
236 }
237 }
238 if (a->argc > 5) {
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]);
241 return CLI_FAILURE;
242 }
243 }
244 duration_ms = duration_sec * 1000;
245 if (!buckets) {
246 buckets = next_prime(key_count);
247 }
248
249 strings = generate_random_strings(key_count);
250 if (!strings) {
251 ast_cli(a->fd, "Failed to generate random strings\n");
252 return CLI_FAILURE;
253 }
254
256 if (!container) {
257 ast_cli(a->fd, "Failed to allocate ao2 container\n");
258 free_random_strings(strings);
259 return CLI_FAILURE;
260 }
261
262 for (i = 0; i < AST_VECTOR_SIZE(strings); i++) {
264 ast_cli(a->fd, "Failed to add string to container\n");
265 ao2_ref(container, -1);
266 free_random_strings(strings);
267 return CLI_FAILURE;
268 }
269 }
270
271 ast_cli(a->fd, "Beginning ao2_string_hash performance test (%d keys, %d seconds, buckets %d)\n",
272 key_count, duration_sec, buckets);
273
274 start = ast_tvnow();
275 for (;;) {
276 int idx = ast_random() % AST_VECTOR_SIZE(strings);
277
279 count++;
280
281 if (ast_tvdiff_ms(ast_tvnow(), start) >= duration_ms) {
282 break;
283 }
284 }
285
286 ast_cli(a->fd, "ao2_string_hash: %u lookups in %d seconds (%u lookups/sec)\n", count, duration_sec, count / duration_sec);
287
288 ao2_ref(container, -1);
289 free_random_strings(strings);
290
291 return CLI_SUCCESS;
292}
#define CLI_SUCCESS
Definition cli.h:44
void ast_cli(int fd, const char *fmt,...)
Definition clicompat.c:6
@ CLI_INIT
Definition cli.h:152
@ CLI_GENERATE
Definition cli.h:153
#define CLI_FAILURE
Definition cli.h:46
struct ao2_container * container
Definition res_fax.c:603
char * command
Definition cli.h:186
const char * usage
Definition cli.h:177
static struct test_val a
static struct ast_vector_string * generate_random_strings(int count)
Generates a vector of random strings to use as keys.
#define DEFAULT_DURATION_SEC
The default duration of the performance test in seconds.
#define DEFAULT_KEY_COUNT
The default number of keys to generate for performance tests.
static int next_prime(int n)
Finds the next prime number greater than or equal to n.
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition time.h:107
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition time.h:159
long int ast_random(void)
Definition utils.c:2346
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition vector.h:637
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition vector.h:708

References a, AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_cleanup, ao2_find, ao2_ref, ast_cli(), ast_random(), ast_str_container_add(), ast_str_container_alloc_options(), ast_tvdiff_ms(), ast_tvnow(), AST_VECTOR_GET, AST_VECTOR_SIZE, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, container, DEFAULT_DURATION_SEC, DEFAULT_KEY_COUNT, free_random_strings(), generate_random_strings(), next_prime(), NULL, OBJ_SEARCH_KEY, and ast_cli_entry::usage.

Referenced by handle_cli_container_key_lookup_all().

◆ handle_cli_ao2_string_list()

static char * handle_cli_ao2_string_list ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Handles the CLI command for testing ao2_container list string lookups.

Parameters
eThe CLI entry
cmdThe command to execute
aThe CLI arguments
Returns
NULL on success, or an error message on failure

Definition at line 431 of file test_performance.c.

432{
433 struct ao2_container *container;
434 struct ast_vector_string *strings;
435 struct timeval start;
436 unsigned int count = 0;
437 int key_count = DEFAULT_KEY_COUNT;
438 int duration_sec = DEFAULT_DURATION_SEC;
439 int duration_ms;
440 int i;
441
442 switch (cmd) {
443 case CLI_INIT:
444 e->command = "performance test ao2_string_list";
445 e->usage =
446 "Usage: performance test ao2_string_list [<num_keys>] [<duration_sec>]\n"
447 " Test the performance of ao2_container list string key lookups.\n";
448 return NULL;
449 case CLI_GENERATE:
450 return NULL;
451 }
452
453 if (a->argc > 3) {
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]);
456 return CLI_FAILURE;
457 }
458 }
459 if (a->argc > 4) {
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]);
462 return CLI_FAILURE;
463 }
464 }
465 duration_ms = duration_sec * 1000;
466
467 strings = generate_random_strings(key_count);
468 if (!strings) {
469 ast_cli(a->fd, "Failed to generate random strings\n");
470 return CLI_FAILURE;
471 }
472
474 if (!container) {
475 ast_cli(a->fd, "Failed to allocate ao2 list container\n");
476 free_random_strings(strings);
477 return CLI_FAILURE;
478 }
479
480 for (i = 0; i < AST_VECTOR_SIZE(strings); i++) {
481 const char *key = AST_VECTOR_GET(strings, i);
482 char *obj = ao2_alloc_options(strlen(key) + 1, NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
483
484 if (!obj) {
485 ast_cli(a->fd, "Failed to allocate object for string\n");
486 ao2_ref(container, -1);
487 free_random_strings(strings);
488 return CLI_FAILURE;
489 }
490 strcpy(obj, key);
491 ao2_link(container, obj);
492 ao2_ref(obj, -1);
493 }
494
495 ast_cli(a->fd, "Beginning ao2_string_list performance test (%d keys, %d seconds)\n",
496 key_count, duration_sec);
497
498 start = ast_tvnow();
499 for (;;) {
500 int idx = ast_random() % AST_VECTOR_SIZE(strings);
501
503 count++;
504
505 if (ast_tvdiff_ms(ast_tvnow(), start) >= duration_ms) {
506 break;
507 }
508 }
509
510 ast_cli(a->fd, "ao2_string_list: %u lookups in %d seconds (%u lookups/sec)\n", count, duration_sec, count / duration_sec);
511
512 ao2_ref(container, -1);
513 free_random_strings(strings);
514
515 return CLI_SUCCESS;
516}
#define ao2_link(container, obj)
Add an object to a container.
Definition astobj2.h:1532
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition astobj2.h:404
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition astobj2.h:1327
static int rbtree_str_sort(const void *lhs, const void *rhs, int flags)
Compares two strings for sorting in the RBTree.
static int rbtree_str_cmp(void *lhs, void *rhs, int flags)
Compares two strings for finding in the RBTree.

References a, AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, ao2_container_alloc_list, ao2_find, ao2_link, ao2_ref, ast_cli(), ast_random(), ast_tvdiff_ms(), ast_tvnow(), AST_VECTOR_GET, AST_VECTOR_SIZE, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, container, DEFAULT_DURATION_SEC, DEFAULT_KEY_COUNT, free_random_strings(), generate_random_strings(), NULL, OBJ_SEARCH_KEY, rbtree_str_cmp(), rbtree_str_sort(), and ast_cli_entry::usage.

Referenced by handle_cli_container_key_lookup_all().

◆ handle_cli_ao2_string_rbtree()

static char * handle_cli_ao2_string_rbtree ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Handles the CLI command for testing ao2_container rbtree string lookups.

Parameters
eThe CLI entry
cmdThe command to execute
aThe CLI arguments
Returns
NULL on success, or an error message on failure

Definition at line 337 of file test_performance.c.

338{
339 struct ao2_container *container;
340 struct ast_vector_string *strings;
341 struct timeval start;
342 unsigned int count = 0;
343 int key_count = DEFAULT_KEY_COUNT;
344 int duration_sec = DEFAULT_DURATION_SEC;
345 int duration_ms;
346 int i;
347
348 switch (cmd) {
349 case CLI_INIT:
350 e->command = "performance test ao2_string_rbtree";
351 e->usage =
352 "Usage: performance test ao2_string_rbtree [<num_keys>] [<duration_sec>]\n"
353 " Test the performance of ao2_container rbtree string key lookups.\n";
354 return NULL;
355 case CLI_GENERATE:
356 return NULL;
357 }
358
359 if (a->argc > 3) {
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]);
362 return CLI_FAILURE;
363 }
364 }
365 if (a->argc > 4) {
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]);
368 return CLI_FAILURE;
369 }
370 }
371 duration_ms = duration_sec * 1000;
372
373 strings = generate_random_strings(key_count);
374 if (!strings) {
375 ast_cli(a->fd, "Failed to generate random strings\n");
376 return CLI_FAILURE;
377 }
378
380 if (!container) {
381 ast_cli(a->fd, "Failed to allocate ao2 rbtree container\n");
382 free_random_strings(strings);
383 return CLI_FAILURE;
384 }
385
386 for (i = 0; i < AST_VECTOR_SIZE(strings); i++) {
387 const char *key = AST_VECTOR_GET(strings, i);
388 char *obj = ao2_alloc_options(strlen(key) + 1, NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
389
390 if (!obj) {
391 ast_cli(a->fd, "Failed to allocate object for string\n");
392 ao2_ref(container, -1);
393 free_random_strings(strings);
394 return CLI_FAILURE;
395 }
396 strcpy(obj, key);
397 ao2_link(container, obj);
398 ao2_ref(obj, -1);
399 }
400
401 ast_cli(a->fd, "Beginning ao2_string_rbtree performance test (%d keys, %d seconds)\n",
402 key_count, duration_sec);
403
404 start = ast_tvnow();
405 for (;;) {
406 int idx = ast_random() % AST_VECTOR_SIZE(strings);
407
409 count++;
410
411 if (ast_tvdiff_ms(ast_tvnow(), start) >= duration_ms) {
412 break;
413 }
414 }
415
416 ast_cli(a->fd, "ao2_string_rbtree: %u lookups in %d seconds (%u lookups/sec)\n", count, duration_sec, count / duration_sec);
417
418 ao2_ref(container, -1);
419 free_random_strings(strings);
420
421 return CLI_SUCCESS;
422}
#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a red-black tree container.
Definition astobj2.h:1349

References a, AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, ao2_container_alloc_rbtree, ao2_find, ao2_link, ao2_ref, ast_cli(), ast_random(), ast_tvdiff_ms(), ast_tvnow(), AST_VECTOR_GET, AST_VECTOR_SIZE, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, container, DEFAULT_DURATION_SEC, DEFAULT_KEY_COUNT, free_random_strings(), generate_random_strings(), NULL, OBJ_SEARCH_KEY, rbtree_str_cmp(), rbtree_str_sort(), and ast_cli_entry::usage.

Referenced by handle_cli_container_key_lookup_all().

◆ handle_cli_container_key_lookup_all()

static char * handle_cli_container_key_lookup_all ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Handles the CLI command for running all container key lookup performance tests.

Parameters
eThe CLI entry
cmdThe command to execute
aThe CLI arguments
Returns
NULL on success, or an error message on failure

Definition at line 948 of file test_performance.c.

949{
950 switch (cmd) {
951 case CLI_INIT:
952 e->command = "performance test container_key_lookup_all";
953 e->usage =
954 "Usage: performance test container_key_lookup_all [<num_keys>] [<duration_sec>] [<buckets>]\n"
955 " Run all performance tests.\n";
956 return NULL;
957 case CLI_GENERATE:
958 return NULL;
959 }
960
961 /*
962 * We don't care if any of these fail because each will output a message if this occurs,
963 * as well we just pass in the arguments unaltered as none of the tests examine the
964 * full command and they also follow the same format as this CLI command -
965 * "performance test <name> <arguments>" so there is no weird difference in where the
966 * arguments they care about are.
967 */
972 handle_cli_list_string(e, cmd, a);
975
976 return CLI_SUCCESS;
977}
static char * handle_cli_ao2_string_list(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Handles the CLI command for testing ao2_container list string lookups.
static char * handle_cli_ao2_string_hash(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Handles the CLI command for testing ao2_container hash string lookups.
static char * handle_cli_vector_bsearch_lookup(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Handles the CLI command for testing vector string binary search lookups.
static char * handle_cli_hashtab_string(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Handles the CLI command for testing hashtab string lookups.
static char * handle_cli_ao2_string_rbtree(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Handles the CLI command for testing ao2_container rbtree string lookups.
static char * handle_cli_vector_linear_lookup(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Handles the CLI command for testing vector string linear search lookups.
static char * handle_cli_list_string(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Handle the 'performance test list_string' command.

References a, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, handle_cli_ao2_string_hash(), handle_cli_ao2_string_list(), handle_cli_ao2_string_rbtree(), handle_cli_hashtab_string(), handle_cli_list_string(), handle_cli_vector_bsearch_lookup(), handle_cli_vector_linear_lookup(), NULL, and ast_cli_entry::usage.

◆ handle_cli_hashtab_string()

static char * handle_cli_hashtab_string ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Handles the CLI command for testing hashtab string lookups.

Parameters
eThe CLI entry
cmdThe command to execute
aThe CLI arguments
Returns
NULL on success, or an error message on failure

Definition at line 534 of file test_performance.c.

535{
536 struct ast_hashtab *tab;
537 struct ast_vector_string *strings;
538 struct timeval start;
539 unsigned int count = 0;
540 int key_count = DEFAULT_KEY_COUNT;
541 int duration_sec = DEFAULT_DURATION_SEC;
542 int duration_ms;
543 int buckets = 0;
544 int i;
545
546 switch (cmd) {
547 case CLI_INIT:
548 e->command = "performance test hashtab_string";
549 e->usage =
550 "Usage: performance test hashtab_string [<num_keys>] [<duration_sec>] [<buckets>]\n"
551 " Test the performance of hashtab string lookups.\n";
552 return NULL;
553 case CLI_GENERATE:
554 return NULL;
555 }
556
557 if (a->argc > 3) {
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]);
560 return CLI_FAILURE;
561 }
562 }
563 if (a->argc > 4) {
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]);
566 return CLI_FAILURE;
567 }
568 }
569 if (a->argc > 5) {
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]);
572 return CLI_FAILURE;
573 }
574 }
575 duration_ms = duration_sec * 1000;
576 if (!buckets) {
577 buckets = next_prime(key_count);
578 }
579
580 strings = generate_random_strings(key_count);
581 if (!strings) {
582 ast_cli(a->fd, "Failed to generate random strings\n");
583 return CLI_FAILURE;
584 }
585
587 if (!tab) {
588 ast_cli(a->fd, "Failed to allocate hashtab\n");
589 free_random_strings(strings);
590 return CLI_FAILURE;
591 }
592
593 for (i = 0; i < AST_VECTOR_SIZE(strings); i++) {
594 char *dup = ast_strdup(AST_VECTOR_GET(strings, i));
595
596 if (!dup || !ast_hashtab_insert_immediate(tab, dup)) {
597 ast_cli(a->fd, "Failed to insert string into hashtab\n");
598 ast_free(dup);
600 free_random_strings(strings);
601 return CLI_FAILURE;
602 }
603 }
604
605 ast_cli(a->fd, "Beginning hashtab_string performance test (%d keys, %d seconds, buckets %d)\n",
606 key_count, duration_sec, buckets);
607
608 start = ast_tvnow();
609 for (;;) {
610 int idx = ast_random() % AST_VECTOR_SIZE(strings);
611
612 ast_hashtab_lookup(tab, AST_VECTOR_GET(strings, idx));
613 count++;
614
615 if (ast_tvdiff_ms(ast_tvnow(), start) >= duration_ms) {
616 break;
617 }
618 }
619
620 ast_cli(a->fd, "hashtab_string: %u lookups in %d seconds (%u lookups/sec)\n", count, duration_sec, count / duration_sec);
621
623 free_random_strings(strings);
624
625 return CLI_SUCCESS;
626}
void ast_hashtab_destroy(struct ast_hashtab *tab, void(*objdestroyfunc)(void *obj))
This func will free the hash table and all its memory.
Definition hashtab.c:363
int ast_hashtab_compare_strings(const void *a, const void *b)
Compares two strings for equality.
Definition hashtab.c:52
#define ast_hashtab_insert_immediate(tab, obj)
Insert without checking.
Definition hashtab.h:290
void * ast_hashtab_lookup(struct ast_hashtab *tab, const void *obj)
Lookup this object in the hash table.
Definition hashtab.c:486
#define ast_hashtab_create(initial_buckets, compare, resize, newsize, hash, do_locking)
Create the hashtable list.
Definition hashtab.h:254
unsigned int ast_hashtab_hash_string(const void *obj)
Hashes a string to a number.
Definition hashtab.c:153
static void hashtab_free_string(void *obj)
Frees a string object placed into a hashtab.

References a, ast_cli(), ast_free, ast_hashtab_compare_strings(), ast_hashtab_create, ast_hashtab_destroy(), ast_hashtab_hash_string(), ast_hashtab_insert_immediate, ast_hashtab_lookup(), ast_random(), ast_strdup, ast_tvdiff_ms(), ast_tvnow(), AST_VECTOR_GET, AST_VECTOR_SIZE, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, DEFAULT_DURATION_SEC, DEFAULT_KEY_COUNT, free_random_strings(), generate_random_strings(), hashtab_free_string(), next_prime(), NULL, and ast_cli_entry::usage.

Referenced by handle_cli_container_key_lookup_all().

◆ handle_cli_list_string()

static char * handle_cli_list_string ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Handle the 'performance test list_string' command.

Parameters
eThe CLI entry
cmdThe command to execute
aThe CLI arguments
Returns
CLI_SUCCESS on success, CLI_FAILURE on error

Definition at line 643 of file test_performance.c.

644{
645 AST_LIST_HEAD_NOLOCK(list_head, list_node) head;
646 struct ast_vector_string *strings;
647 struct list_node *node;
648 struct timeval start;
649 unsigned int count = 0;
650 int key_count = DEFAULT_KEY_COUNT;
651 int duration_sec = DEFAULT_DURATION_SEC;
652 int duration_ms;
653 int i;
654
655 switch (cmd) {
656 case CLI_INIT:
657 e->command = "performance test list_string";
658 e->usage =
659 "Usage: performance test list_string [<num_keys>] [<duration_sec>]\n"
660 " Test the performance of linked list string key lookups.\n";
661 return NULL;
662 case CLI_GENERATE:
663 return NULL;
664 }
665
666 if (a->argc > 3) {
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]);
669 return CLI_FAILURE;
670 }
671 }
672 if (a->argc > 4) {
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]);
675 return CLI_FAILURE;
676 }
677 }
678 duration_ms = duration_sec * 1000;
679
680 strings = generate_random_strings(key_count);
681 if (!strings) {
682 ast_cli(a->fd, "Failed to generate random strings\n");
683 return CLI_FAILURE;
684 }
685
687
688 for (i = 0; i < AST_VECTOR_SIZE(strings); i++) {
689 node = ast_calloc(1, sizeof(*node));
690 if (!node) {
691 ast_cli(a->fd, "Failed to allocate list node\n");
692 goto cleanup;
693 }
694
695 node->str = ast_strdup(AST_VECTOR_GET(strings, i));
696 if (!node->str) {
697 ast_free(node);
698 ast_cli(a->fd, "Failed to duplicate list node string\n");
699 goto cleanup;
700 }
701
702 AST_LIST_INSERT_TAIL(&head, node, list);
703 }
704
705 ast_cli(a->fd, "Beginning list_string performance test (%d keys, %d seconds)\n",
706 key_count, duration_sec);
707
708 start = ast_tvnow();
709 for (;;) {
710 int idx = ast_random() % AST_VECTOR_SIZE(strings);
711
712 AST_LIST_TRAVERSE(&head, node, list) {
713 if (!strcmp(node->str, AST_VECTOR_GET(strings, idx))) {
714 break;
715 }
716 }
717 count++;
718
719 if (ast_tvdiff_ms(ast_tvnow(), start) >= duration_ms) {
720 break;
721 }
722 }
723
724 ast_cli(a->fd, "list_string: %u lookups in %d seconds (%u lookups/sec)\n", count, duration_sec, count / duration_sec);
725
726cleanup:
727 while ((node = AST_LIST_REMOVE_HEAD(&head, list))) {
728 ast_free(node->str);
729 ast_free(node);
730 }
731
732 free_random_strings(strings);
733
734 return CLI_SUCCESS;
735}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition astmm.h:202
#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_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
static void cleanup(void)
Clean up any old apps that we don't need any more.
Definition res_stasis.c:327
A node in the linked list for string lookups.

References a, ast_calloc, ast_cli(), ast_free, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, ast_random(), ast_strdup, ast_tvdiff_ms(), ast_tvnow(), AST_VECTOR_GET, AST_VECTOR_SIZE, cleanup(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, DEFAULT_DURATION_SEC, DEFAULT_KEY_COUNT, free_random_strings(), generate_random_strings(), NULL, and ast_cli_entry::usage.

Referenced by handle_cli_container_key_lookup_all().

◆ handle_cli_vector_bsearch_lookup()

static char * handle_cli_vector_bsearch_lookup ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Handles the CLI command for testing vector string binary search lookups.

Parameters
eThe CLI entry
cmdThe command to execute
aThe CLI arguments
Returns
NULL on success, or an error message on failure

Definition at line 744 of file test_performance.c.

745{
746 struct ast_vector_string *strings;
747 struct ast_vector_string vec;
748 struct timeval start;
749 unsigned int count = 0;
750 int key_count = DEFAULT_KEY_COUNT;
751 int duration_sec = DEFAULT_DURATION_SEC;
752 int duration_ms;
753 int i;
754
755 switch (cmd) {
756 case CLI_INIT:
757 e->command = "performance test vector_string_bsearch";
758 e->usage =
759 "Usage: performance test vector_string_bsearch [<num_keys>] [<duration_sec>]\n"
760 " Test the performance of vector string key binary search lookups.\n";
761 return NULL;
762 case CLI_GENERATE:
763 return NULL;
764 }
765
766 if (a->argc > 3) {
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]);
769 return CLI_FAILURE;
770 }
771 }
772 if (a->argc > 4) {
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]);
775 return CLI_FAILURE;
776 }
777 }
778 duration_ms = duration_sec * 1000;
779
780 strings = generate_random_strings(key_count);
781 if (!strings) {
782 ast_cli(a->fd, "Failed to generate random strings\n");
783 return CLI_FAILURE;
784 }
785
786 if (AST_VECTOR_INIT(&vec, key_count)) {
787 ast_cli(a->fd, "Failed to initialize vector\n");
788 free_random_strings(strings);
789 return CLI_FAILURE;
790 }
791
792 for (i = 0; i < AST_VECTOR_SIZE(strings); i++) {
793 char *dup = ast_strdup(AST_VECTOR_GET(strings, i));
794
795 if (!dup) {
796 ast_cli(a->fd, "Failed to add string to vector\n");
798 AST_VECTOR_FREE(&vec);
799 free_random_strings(strings);
800 return CLI_FAILURE;
801 }
802
803 /* This can't fail as we're appending to a vector that we know is large enough */
804 AST_VECTOR_APPEND(&vec, dup);
805 }
806
808
809 ast_cli(a->fd, "Beginning vector_string_bsearch performance test (%d keys, %d seconds)\n",
810 key_count, duration_sec);
811
812 start = ast_tvnow();
813 for (;;) {
814 int idx = ast_random() % AST_VECTOR_SIZE(strings);
815 const char **key;
816
817 /*
818 * Unlike the other tests this actually stores the result in a variable and uses it
819 * for determining if the count should be increased. This is done to ensure the compiler
820 * doesn't pull some funny business and optimize away the bsearch call.
821 */
822 key = AST_VECTOR_BSEARCH(&vec, AST_VECTOR_GET(strings, idx), vector_string_cmp);
823 if (key) {
824 count++;
825 }
826
827 if (ast_tvdiff_ms(ast_tvnow(), start) >= duration_ms) {
828 break;
829 }
830 }
831
832 ast_cli(a->fd, "vector_string_bsearch: %u lookups in %d seconds (%u lookups/sec)\n", count, duration_sec, count / duration_sec);
833
835 AST_VECTOR_FREE(&vec);
836 free_random_strings(strings);
837
838 return CLI_SUCCESS;
839}
static int vector_string_cmp(const void *_a, const void *_b)
Compares two strings for sorting.
#define AST_VECTOR_BSEARCH(vec, key, cmp)
Binary search a sorted vector.
Definition vector.h:422
#define AST_VECTOR_SORT(vec, cmp)
Sort a vector in-place.
Definition vector.h:407

References a, ast_cli(), ast_free, ast_random(), ast_strdup, ast_tvdiff_ms(), ast_tvnow(), AST_VECTOR_APPEND, AST_VECTOR_BSEARCH, AST_VECTOR_FREE, AST_VECTOR_GET, AST_VECTOR_INIT, AST_VECTOR_RESET, AST_VECTOR_SIZE, AST_VECTOR_SORT, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, DEFAULT_DURATION_SEC, DEFAULT_KEY_COUNT, free_random_strings(), generate_random_strings(), NULL, ast_cli_entry::usage, and vector_string_cmp().

Referenced by handle_cli_container_key_lookup_all().

◆ handle_cli_vector_linear_lookup()

static char * handle_cli_vector_linear_lookup ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Handles the CLI command for testing vector string linear search lookups.

Parameters
eThe CLI entry
cmdThe command to execute
aThe CLI arguments
Returns
NULL on success, or an error message on failure

Definition at line 848 of file test_performance.c.

849{
850 struct ast_vector_string *strings;
851 struct ast_vector_string vec;
852 struct timeval start;
853 unsigned int count = 0;
854 const char *target;
855 int key_count = DEFAULT_KEY_COUNT;
856 int duration_sec = DEFAULT_DURATION_SEC;
857 int duration_ms;
858 int i;
859
860 switch (cmd) {
861 case CLI_INIT:
862 e->command = "performance test vector_string_linear";
863 e->usage =
864 "Usage: performance test vector_string_linear [<num_keys>] [<duration_sec>]\n"
865 " Test the performance of vector string linear search lookups.\n";
866 return NULL;
867 case CLI_GENERATE:
868 return NULL;
869 }
870
871 if (a->argc > 3) {
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]);
874 return CLI_FAILURE;
875 }
876 }
877 if (a->argc > 4) {
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]);
880 return CLI_FAILURE;
881 }
882 }
883 duration_ms = duration_sec * 1000;
884
885 strings = generate_random_strings(key_count);
886 if (!strings) {
887 ast_cli(a->fd, "Failed to generate random strings\n");
888 return CLI_FAILURE;
889 }
890
891 if (AST_VECTOR_INIT(&vec, key_count)) {
892 ast_cli(a->fd, "Failed to initialize vector\n");
893 free_random_strings(strings);
894 return CLI_FAILURE;
895 }
896
897 for (i = 0; i < AST_VECTOR_SIZE(strings); i++) {
898 char *dup = ast_strdup(AST_VECTOR_GET(strings, i));
899
900 if (!dup) {
901 ast_cli(a->fd, "Failed to add string to vector\n");
903 AST_VECTOR_FREE(&vec);
904 free_random_strings(strings);
905 return CLI_FAILURE;
906 }
907
908 /* This can't fail as we're appending to a vector that we know is large enough */
909 AST_VECTOR_APPEND(&vec, dup);
910 }
911
912 ast_cli(a->fd, "Beginning vector_string_linear performance test (%d keys, %d seconds)\n",
913 key_count, duration_sec);
914
915 start = ast_tvnow();
916 for (;;) {
917 int idx = ast_random() % AST_VECTOR_SIZE(strings);
918
919 target = AST_VECTOR_GET(strings, idx);
920 for (i = 0; i < AST_VECTOR_SIZE(&vec); i++) {
921 if (!strcmp(AST_VECTOR_GET(&vec, i), target)) {
922 break;
923 }
924 }
925 count++;
926
927 if (ast_tvdiff_ms(ast_tvnow(), start) >= duration_ms) {
928 break;
929 }
930 }
931
932 ast_cli(a->fd, "vector_string_linear: %u lookups in %d seconds (%u lookups/sec)\n", count, duration_sec, count / duration_sec);
933
935 AST_VECTOR_FREE(&vec);
936 free_random_strings(strings);
937
938 return CLI_SUCCESS;
939}

References a, ast_cli(), ast_free, ast_random(), ast_strdup, ast_tvdiff_ms(), ast_tvnow(), AST_VECTOR_APPEND, AST_VECTOR_FREE, AST_VECTOR_GET, AST_VECTOR_INIT, AST_VECTOR_RESET, AST_VECTOR_SIZE, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, DEFAULT_DURATION_SEC, DEFAULT_KEY_COUNT, free_random_strings(), generate_random_strings(), NULL, and ast_cli_entry::usage.

Referenced by handle_cli_container_key_lookup_all().

◆ hashtab_free_string()

static void hashtab_free_string ( void *  obj)
static

Frees a string object placed into a hashtab.

Parameters
objThe string object to free

Definition at line 522 of file test_performance.c.

523{
524 ast_free(obj);
525}

References ast_free.

Referenced by handle_cli_hashtab_string().

◆ load_module()

static int load_module ( void  )
static

Loads the performance testing module.

Returns
AST_MODULE_LOAD_SUCCESS on success

Definition at line 1007 of file test_performance.c.

1008{
1011}
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition cli.h:265
@ AST_MODULE_LOAD_SUCCESS
Definition module.h:70
static struct ast_cli_entry cli_performance[]
The CLI commands for performance experimentation testing.
#define ARRAY_LEN(a)
Definition utils.h:706

References ARRAY_LEN, ast_cli_register_multiple, AST_MODULE_LOAD_SUCCESS, and cli_performance.

◆ next_prime()

static int next_prime ( int  n)
static

Finds the next prime number greater than or equal to n.

Parameters
nThe number to find the next prime for
Returns
The next prime number

Definition at line 173 of file test_performance.c.

174{
175 /*
176 * The lowest prime number is 2. It's also the only even prime number, that fact
177 * is of absolutely no relevance to this module but I put it here just for fun
178 */
179 if (n <= 2) {
180 return 2;
181 }
182
183 /* If it's divisible by 2, increment to the next odd number so we can find the next prime easier */
184 if (n % 2 == 0) {
185 n++;
186 }
187
188 /* Loop until we find a prime number */
189 while (!ast_is_prime(n)) {
190 n += 2;
191 }
192
193 return n;
194}
int ast_is_prime(int num)
Determines if the specified number is prime.
Definition hashtab.c:101

References ast_is_prime().

Referenced by handle_cli_ao2_string_hash(), and handle_cli_hashtab_string().

◆ rbtree_str_cmp()

static int rbtree_str_cmp ( void *  lhs,
void *  rhs,
int  flags 
)
static

Compares two strings for finding in the RBTree.

Parameters
lhsThe first string to compare
rhsThe second string to compare
flagsThe search flags
Returns
The result of the comparison

Definition at line 317 of file test_performance.c.

318{
319 int cmp = 0;
320
321 if ((flags & OBJ_SEARCH_MASK) == OBJ_SEARCH_PARTIAL_KEY) {
322 cmp = strncmp(lhs, rhs, strlen(rhs));
323 } else {
324 cmp = strcmp(lhs, rhs);
325 }
326
327 return cmp ? 0 : CMP_MATCH;
328}
@ CMP_MATCH
Definition astobj2.h:1027
@ OBJ_SEARCH_PARTIAL_KEY
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Definition astobj2.h:1116
@ OBJ_SEARCH_MASK
Search option field mask.
Definition astobj2.h:1072

References CMP_MATCH, OBJ_SEARCH_MASK, and OBJ_SEARCH_PARTIAL_KEY.

Referenced by handle_cli_ao2_string_list(), and handle_cli_ao2_string_rbtree().

◆ rbtree_str_sort()

static int rbtree_str_sort ( const void *  lhs,
const void *  rhs,
int  flags 
)
static

Compares two strings for sorting in the RBTree.

Parameters
lhsThe first string to compare
rhsThe second string to compare
flagsThe search flags
Returns
The result of the comparison

Definition at line 301 of file test_performance.c.

302{
303 if ((flags & OBJ_SEARCH_MASK) == OBJ_SEARCH_PARTIAL_KEY) {
304 return strncmp(lhs, rhs, strlen(rhs));
305 } else {
306 return strcmp(lhs, rhs);
307 }
308}

References OBJ_SEARCH_MASK, and OBJ_SEARCH_PARTIAL_KEY.

Referenced by handle_cli_ao2_string_list(), and handle_cli_ao2_string_rbtree().

◆ unload_module()

static int unload_module ( void  )
static

Unloads the performance testing module.

Returns
0 on success

Definition at line 997 of file test_performance.c.

998{
1000 return 0;
1001}
void ast_cli_unregister_multiple(void)
Definition ael_main.c:408

References ARRAY_LEN, ast_cli_unregister_multiple(), and cli_performance.

◆ vector_string_cmp()

static int vector_string_cmp ( const void *  _a,
const void *  _b 
)
static

Compares two strings for sorting.

Parameters
aThe first string to compare
bThe second string to compare
Returns
The result of the comparison

Definition at line 161 of file test_performance.c.

162{
163 const char *a = *(const char **)_a;
164 const char *b = *(const char **)_b;
165 return strcmp(a, b);
166}
static struct test_val b

References a, and b.

Referenced by handle_cli_vector_bsearch_lookup().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Performance Test Experimentation Module" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 1013 of file test_performance.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1013 of file test_performance.c.

◆ cli_performance

struct ast_cli_entry cli_performance[]
static

The CLI commands for performance experimentation testing.

Definition at line 982 of file test_performance.c.

982 {
983 AST_CLI_DEFINE(handle_cli_container_key_lookup_all, "Run all performance tests"),
984 AST_CLI_DEFINE(handle_cli_ao2_string_hash, "Test the performance of ao2_container hash string lookups"),
985 AST_CLI_DEFINE(handle_cli_ao2_string_rbtree, "Test the performance of ao2_container rbtree string lookups"),
986 AST_CLI_DEFINE(handle_cli_ao2_string_list, "Test the performance of ao2_container list string lookups"),
987 AST_CLI_DEFINE(handle_cli_hashtab_string, "Test the performance of hashtab string lookups"),
988 AST_CLI_DEFINE(handle_cli_list_string, "Test the performance of linked list string lookups"),
989 AST_CLI_DEFINE(handle_cli_vector_bsearch_lookup, "Test the performance of vector string binary search lookups"),
990 AST_CLI_DEFINE(handle_cli_vector_linear_lookup, "Test the performance of vector string linear search lookups"),
991};
#define AST_CLI_DEFINE(fn, txt,...)
Definition cli.h:197
static char * handle_cli_container_key_lookup_all(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Handles the CLI command for running all container key lookup performance tests.

Referenced by load_module(), and unload_module().