[asterisk-commits] rmudgett: branch rmudgett/ao2_red_black r371722 - in /team/rmudgett/ao2_red_b...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Aug 27 12:16:11 CDT 2012
Author: rmudgett
Date: Mon Aug 27 12:16:07 2012
New Revision: 371722
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=371722
Log:
Add rbtree dev-mode stats.
Modified:
team/rmudgett/ao2_red_black/include/asterisk/astobj2.h
team/rmudgett/ao2_red_black/main/astobj2.c
Modified: team/rmudgett/ao2_red_black/include/asterisk/astobj2.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/ao2_red_black/include/asterisk/astobj2.h?view=diff&rev=371722&r1=371721&r2=371722
==============================================================================
--- team/rmudgett/ao2_red_black/include/asterisk/astobj2.h (original)
+++ team/rmudgett/ao2_red_black/include/asterisk/astobj2.h Mon Aug 27 12:16:07 2012
@@ -1298,6 +1298,18 @@
#define ao2_container_clone(orig, flags) __ao2_container_clone(orig, flags)
#endif
+
+/*!
+ * \brief Display statistics of the specified container.
+ * \since 12.0.0
+ *
+ * \param self Container to display statistics.
+ * \param fd File descriptor to send output.
+ * \param prnt Print output callback function to use.
+ *
+ * \return Nothing
+ */
+void ao2_container_stats(struct ao2_container *self, int fd, void (*prnt)(int fd, const char *fmt, ...) __attribute__((format(printf, 2, 3))));
/*!
* \brief Perform an integrity check on the specified container.
Modified: team/rmudgett/ao2_red_black/main/astobj2.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/ao2_red_black/main/astobj2.c?view=diff&rev=371722&r1=371721&r2=371722
==============================================================================
--- team/rmudgett/ao2_red_black/main/astobj2.c (original)
+++ team/rmudgett/ao2_red_black/main/astobj2.c Mon Aug 27 12:16:07 2012
@@ -92,6 +92,12 @@
struct __priv_data priv_data;
void *user_data[0];
};
+
+#if defined(AST_DEVMODE)
+#define AO2_DEVMODE_STAT(stat) stat
+#else
+#define AO2_DEVMODE_STAT(stat)
+#endif /* defined(AST_DEVMODE) */
#ifdef AO2_DEBUG
struct ao2_stats {
@@ -1039,7 +1045,7 @@
node->is_linked = 1;
ast_atomic_fetchadd_int(&self->elements, 1);
#if defined(AST_DEVMODE)
- ++self->nodes;
+ AO2_DEVMODE_STAT(++self->nodes);
switch (self->v_table->type) {
case AO2_CONTAINER_RTTI_HASH:
hash_ao2_link_node_stat(self, node);
@@ -1761,19 +1767,7 @@
return clone;
}
-#if defined(AST_DEVMODE)
-/*!
- * \internal
- * \brief Display statistics of the specified container.
- * \since 12.0.0
- *
- * \param self Container to display statistics.
- * \param fd File descriptor to send output.
- * \param prnt Print output callback function to use.
- *
- * \return Nothing
- */
-static void ao2_container_stats(struct ao2_container *self, int fd, void (*prnt)(int fd, const char *fmt, ...) __attribute__((format(printf, 2, 3))))
+void ao2_container_stats(struct ao2_container *self, int fd, void (*prnt)(int fd, const char *fmt, ...) __attribute__((format(printf, 2, 3))))
{
if (!INTERNAL_OBJ(self) || !self->v_table) {
prnt(fd, "Invalid container\n");
@@ -1783,6 +1777,7 @@
ao2_rdlock(self);
prnt(fd, "Number of objects: %d\n", self->elements);
+#if defined(AST_DEVMODE)
prnt(fd, "Number of nodes: %d\n", self->nodes);
prnt(fd, "Number of empty nodes: %d\n", self->nodes - self->elements);
/*
@@ -1798,9 +1793,9 @@
if (self->v_table->stats) {
self->v_table->stats(self, fd, prnt);
}
+#endif /* defined(AST_DEVMODE) */
ao2_unlock(self);
}
-#endif /* defined(AST_DEVMODE) */
int ao2_container_check(struct ao2_container *self, enum search_flags flags)
{
@@ -1975,9 +1970,7 @@
bucket = &my_container->buckets[doomed->my_bucket];
AST_DLLIST_REMOVE(&bucket->list, doomed, links);
-#if defined(AST_DEVMODE)
- --my_container->common.nodes;
-#endif /* defined(AST_DEVMODE) */
+ AO2_DEVMODE_STAT(--my_container->common.nodes);
}
/*
@@ -3070,9 +3063,20 @@
struct ao2_container common;
/*! Root node of the tree. NULL if the tree is empty. */
struct rbtree_node *root;
-/* BUGBUG need to add stats counters for fixup insert left/right cases 1-3 */
-/* BUGBUG need to add stats counters for fixup delete left/right cases 1-4 */
-/* BUGBUG need to add stats counter for delete in middle of tree. */
+#if defined(AST_DEVMODE)
+ struct {
+ /*! Fixup insert left cases 1-3 */
+ int fixup_insert_left[3];
+ /*! Fixup insert right cases 1-3 */
+ int fixup_insert_right[3];
+ /*! Fixup delete left cases 1-4 */
+ int fixup_delete_left[4];
+ /*! Fixup delete right cases 1-4 */
+ int fixup_delete_right[4];
+ /*! Deletion of node with number of children (0-2). */
+ int delete_children[3];
+ } stats;
+#endif /* defined(AST_DEVMODE) */
};
/*!
@@ -3561,6 +3565,7 @@
ast_assert(sibling != NULL);
if (sibling->is_red) {
/* Case 1: The child's sibling is red. */
+ AO2_DEVMODE_STAT(++self->stats.fixup_delete_left[0]);
sibling->is_red = 0;
child->parent->is_red = 1;
rb_rotate_left(self, child->parent);
@@ -3570,11 +3575,13 @@
if ((!sibling->left || !sibling->left->is_red)
&& (!sibling->right || !sibling->right->is_red)) {
/* Case 2: The sibling is black and both of its children are black. */
+ AO2_DEVMODE_STAT(++self->stats.fixup_delete_left[1]);
sibling->is_red = 1;
child = child->parent;
} else {
if (!sibling->right || !sibling->right->is_red) {
/* Case 3: The sibling is black, its left child is red, and its right child is black. */
+ AO2_DEVMODE_STAT(++self->stats.fixup_delete_left[2]);
if (sibling->left) {
sibling->left->is_red = 0;
}
@@ -3584,6 +3591,7 @@
ast_assert(sibling != NULL);
}
/* Case 4: The sibling is black and its right child is red. */
+ AO2_DEVMODE_STAT(++self->stats.fixup_delete_left[3]);
sibling->is_red = child->parent->is_red;
child->parent->is_red = 0;
if (sibling->right) {
@@ -3598,6 +3606,7 @@
ast_assert(sibling != NULL);
if (sibling->is_red) {
/* Case 1: The child's sibling is red. */
+ AO2_DEVMODE_STAT(++self->stats.fixup_delete_right[0]);
sibling->is_red = 0;
child->parent->is_red = 1;
rb_rotate_right(self, child->parent);
@@ -3607,11 +3616,13 @@
if ((!sibling->right || !sibling->right->is_red)
&& (!sibling->left || !sibling->left->is_red)) {
/* Case 2: The sibling is black and both of its children are black. */
+ AO2_DEVMODE_STAT(++self->stats.fixup_delete_right[1]);
sibling->is_red = 1;
child = child->parent;
} else {
if (!sibling->left || !sibling->left->is_red) {
/* Case 3: The sibling is black, its right child is red, and its left child is black. */
+ AO2_DEVMODE_STAT(++self->stats.fixup_delete_right[2]);
if (sibling->right) {
sibling->right->is_red = 0;
}
@@ -3621,6 +3632,7 @@
ast_assert(sibling != NULL);
}
/* Case 4: The sibling is black and its left child is red. */
+ AO2_DEVMODE_STAT(++self->stats.fixup_delete_right[3]);
sibling->is_red = child->parent->is_red;
child->parent->is_red = 0;
if (sibling->left) {
@@ -3659,6 +3671,7 @@
* Find the next child node and swap it with the doomed node in
* the tree.
*/
+ AO2_DEVMODE_STAT(++self->stats.delete_children[2]);
next = rb_node_most_left(doomed->right);
SWAP(doomed->parent, next->parent);
SWAP(doomed->left, next->left);
@@ -3698,6 +3711,11 @@
if (!child) {
child = doomed->right;
}
+ }
+ if (child) {
+ AO2_DEVMODE_STAT(++self->stats.delete_children[1]);
+ } else {
+ AO2_DEVMODE_STAT(++self->stats.delete_children[0]);
}
need_fixup = (!doomed->is_red && !self->common.destroying);
@@ -3732,9 +3750,7 @@
}
}
-#if defined(AST_DEVMODE)
- --self->common.nodes;
-#endif /* defined(AST_DEVMODE) */
+ AO2_DEVMODE_STAT(--self->common.nodes);
}
/*!
@@ -3851,6 +3867,7 @@
/* The parent is a left child. */
if (g_parent->right && g_parent->right->is_red) {
/* Case 1: Push the black down from the grand parent node. */
+ AO2_DEVMODE_STAT(++self->stats.fixup_insert_left[0]);
g_parent->right->is_red = 0;
g_parent->left->is_red = 0;
g_parent->is_red = 1;
@@ -3864,10 +3881,12 @@
*
* Which node is the grand parent does not change.
*/
+ AO2_DEVMODE_STAT(++self->stats.fixup_insert_left[1]);
node = node->parent;
rb_rotate_left(self, node);
}
/* Case 3: The node is a left child. */
+ AO2_DEVMODE_STAT(++self->stats.fixup_insert_left[2]);
node->parent->is_red = 0;
g_parent->is_red = 1;
rb_rotate_right(self, g_parent);
@@ -3876,6 +3895,7 @@
/* The parent is a right child. */
if (g_parent->left && g_parent->left->is_red) {
/* Case 1: Push the black down from the grand parent node. */
+ AO2_DEVMODE_STAT(++self->stats.fixup_insert_right[0]);
g_parent->left->is_red = 0;
g_parent->right->is_red = 0;
g_parent->is_red = 1;
@@ -3889,10 +3909,12 @@
*
* Which node is the grand parent does not change.
*/
+ AO2_DEVMODE_STAT(++self->stats.fixup_insert_right[1]);
node = node->parent;
rb_rotate_right(self, node);
}
/* Case 3: The node is a right child. */
+ AO2_DEVMODE_STAT(++self->stats.fixup_insert_right[2]);
node->parent->is_red = 0;
g_parent->is_red = 1;
rb_rotate_left(self, g_parent);
@@ -4588,6 +4610,48 @@
ast_assert(0);
}
}
+
+#if defined(AST_DEVMODE)
+/*!
+ * \internal
+ * \brief Display statistics of the specified container.
+ * \since 12.0.0
+ *
+ * \param self Container to display statistics.
+ * \param fd File descriptor to send output.
+ * \param prnt Print output callback function to use.
+ *
+ * \note The container is already locked for reading.
+ *
+ * \return Nothing
+ */
+static void rb_ao2_stats(struct ao2_container_rbtree *self, int fd, void (*prnt)(int fd, const char *fmt, ...) __attribute__((format(printf, 2, 3))))
+{
+ int idx;
+
+ for (idx = 0; idx < ARRAY_LEN(self->stats.fixup_insert_left); ++idx) {
+ prnt(fd, "Number of left insert fixups case %d: %d\n", idx + 1,
+ self->stats.fixup_insert_left[idx]);
+ }
+ for (idx = 0; idx < ARRAY_LEN(self->stats.fixup_insert_right); ++idx) {
+ prnt(fd, "Number of right insert fixups case %d: %d\n", idx + 1,
+ self->stats.fixup_insert_right[idx]);
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(self->stats.delete_children); ++idx) {
+ prnt(fd, "Number of nodes deleted with %d children: %d\n", idx,
+ self->stats.delete_children[idx]);
+ }
+ for (idx = 0; idx < ARRAY_LEN(self->stats.fixup_delete_left); ++idx) {
+ prnt(fd, "Number of left delete fixups case %d: %d\n", idx + 1,
+ self->stats.fixup_delete_left[idx]);
+ }
+ for (idx = 0; idx < ARRAY_LEN(self->stats.fixup_delete_right); ++idx) {
+ prnt(fd, "Number of right delete fixups case %d: %d\n", idx + 1,
+ self->stats.fixup_delete_right[idx]);
+ }
+}
+#endif /* defined(AST_DEVMODE) */
#if defined(AST_DEVMODE)
/*!
@@ -4750,6 +4814,7 @@
.iterator_next = (ao2_iterator_next_fn) rb_ao2_iterator_next,
.destroy = (ao2_container_destroy_fn) rb_ao2_destroy,
#if defined(AST_DEVMODE)
+ .stats = (ao2_container_statistics) rb_ao2_stats,
.integrity = (ao2_container_integrity) rb_ao2_integrity,
#endif /* defined(AST_DEVMODE) */
};
More information about the asterisk-commits
mailing list