Addition of hashtable iterator

User print routine

rejig of show users to show dbusers and a new show users command in the debugcli
This commit is contained in:
Mark Riddoch
2013-07-23 12:16:22 +02:00
parent 36f62637c9
commit 016e759b2b
6 changed files with 126 additions and 1 deletions

View File

@ -185,3 +185,14 @@ admin_test_user(char *user)
return 0;
return users_fetch(users, user) != NULL;
}
/**
* Print the statistics and user names of the administration users
*
* @param dcb A DCB to send the output to
*/
void
dcb_PrintAdminUsers(DCB *dcb)
{
dcb_usersPrint(dcb, users);
}

View File

@ -51,6 +51,7 @@
*
* Date Who Description
* 23/06/13 Mark Riddoch Initial implementation
* 23/07/13 Mark Riddoch Addition of hashtable iterator
*
* @endverbatim
*/
@ -437,3 +438,68 @@ hashtable_write_unlock(HASHTABLE *table)
{
atomic_add(&table->writelock, -1);
}
/**
* Create an iterator on a hash table
*
* @param table The table to ceate an iterator on
* @return An iterator to use in future calls
*/
HASHITERATOR *
hashtable_iterator(HASHTABLE *table)
{
HASHITERATOR *rval;
if ((rval = (HASHITERATOR *)malloc(sizeof(HASHITERATOR))) != NULL)
{
rval->table = table;
rval->chain = 0;
rval->depth = -1;
}
return rval;
}
/**
* Return the next key for a hashtable iterator
*
* @param iter The hashtable iterator
* @return The next key value or NULL
*/
void *
hashtable_next(HASHITERATOR *iter)
{
int i;
HASHENTRIES *entries;
iter->depth++;
while (iter->chain < iter->table->hashsize)
{
if ((entries = iter->table->entries[iter->chain]) != NULL)
{
i = 0;
hashtable_read_lock(iter->table);
while (entries && i < iter->depth)
{
entries = entries->next;
i++;
}
hashtable_read_unlock(iter->table);
if (entries)
return entries->key;
}
iter->depth = 0;
iter->chain++;
}
return NULL;
}
/**
* Free a hashtable iterator
*
* @param iter The iterator to free
*/
void
hashtable_iterator_free(HASHITERATOR *iter)
{
free(iter);
}

View File

@ -170,6 +170,20 @@ usersPrint(USERS *users)
void
dcb_usersPrint(DCB *dcb, USERS *users)
{
HASHITERATOR *iter;
char *sep, *user;
dcb_printf(dcb, "Users table data\n");
dcb_hashtable_stats(dcb, users->data);
if ((iter = hashtable_iterator(users->data)) != NULL)
{
dcb_printf(dcb, "User names: ");
sep = "";
while ((user = hashtable_next(iter)) != NULL)
{
dcb_printf(dcb, "%s%s", sep, user);
sep = ", ";
}
dcb_printf(dcb, "\n");
}
}

View File

@ -34,5 +34,7 @@
extern int admin_verify(char *, char *);
extern char *admin_add_user(char *, char *);
extern int admin_test_user(char *);
extern void dcb_PrintAdminUsers(DCB *dcb);
#endif

View File

@ -27,6 +27,7 @@
*
* Date Who Description
* 23/06/13 Mark Riddoch Initial implementation
* 23/07/13 Mark Riddoch Addition of iterator mechanism
*
* @endverbatim
*/
@ -46,6 +47,17 @@ typedef struct hashentry {
struct hashentry *next; /**< The overflow chain */
} HASHENTRIES;
/**
* HASHTABLE iterator - used to walk the hashtable in a thread safe
* way
*/
typedef struct hashiterator {
struct hashtable
*table; /**< The hashtable the iterator refers to */
int chain; /**< The current chain we are walking */
int depth; /**< The current depth down the chain */
} HASHITERATOR;
/**
* The type definition for the memory allocation functions
*/
@ -80,4 +92,9 @@ extern void *hashtable_fetch(HASHTABLE *, void *);
/**< Fetch the data for a given key */
extern void hashtable_stats(HASHTABLE *); /**< Print statisitics */
extern void dcb_hashtable_stats(DCB *, HASHTABLE *); /**< Print statisitics */
extern HASHITERATOR *hashtable_iterator(HASHTABLE *);
/**< Allocate an iterator on the hashtable */
extern void *hashtable_next(HASHITERATOR *);
/**< Return the key of the hash table iterator */
extern void hashtable_iterator_free(HASHITERATOR *);
#endif

View File

@ -75,6 +75,7 @@ struct subcommand {
int arg_types[3];
};
static void telnetdShowUsers(DCB *);
/**
* The subcommands of the show command
*/
@ -97,7 +98,9 @@ struct subcommand showoptions[] = {
{ARG_TYPE_ADDRESS, 0, 0} },
{ "epoll", 0, dprintPollStats, "Show the poll statistics",
{0, 0, 0} },
{ "users", 1, dcb_usersPrint, "Show statistics for a users table",
{ "dbusers", 1, dcb_usersPrint, "Show statistics and user names for a service's user table",
{ARG_TYPE_ADDRESS, 0, 0} },
{ "users", 0, telnetdShowUsers, "Show statistics and user names for the debug interface",
{ARG_TYPE_ADDRESS, 0, 0} },
{ NULL, 0, NULL, NULL,
{0, 0, 0} }
@ -503,3 +506,15 @@ char *err;
else
dcb_printf(dcb, "Failed to add new user. %s\n", err);
}
/**
* Print the adminsitration users
*
* @param dcb The DCB to print the user data to
*/
static void
telnetdShowUsers(DCB *dcb)
{
dcb_printf(dcb, "Administration interface users:\n");
dcb_PrintAdminUsers(dcb);
}