[svn-commits] mmichelson: branch mmichelson/rls-subscribe r417700 - /team/mmichelson/rls-su...
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Mon Jun 30 16:40:50 CDT 2014
Author: mmichelson
Date: Mon Jun 30 16:40:45 2014
New Revision: 417700
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=417700
Log:
Implement a scheme for detecting loops/duplicated resources.
Each resource that is visited is added to a vector. When visiting
a new resource, we check if the resource exists in the vector.
It's not a very efficient algorithm since seeing if the resource
has been visited is an O(N) operation. It could be sped up by
using a different container type, though I'd first like to
verify the algorithm's correctness before optimizing.
Modified:
team/mmichelson/rls-subscribe/res/res_pjsip_pubsub.c
Modified: team/mmichelson/rls-subscribe/res/res_pjsip_pubsub.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/rls-subscribe/res/res_pjsip_pubsub.c?view=diff&rev=417700&r1=417699&r2=417700
==============================================================================
--- team/mmichelson/rls-subscribe/res/res_pjsip_pubsub.c (original)
+++ team/mmichelson/rls-subscribe/res/res_pjsip_pubsub.c Mon Jun 30 16:40:45 2014
@@ -633,6 +633,8 @@
struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, const char *resource,
struct ast_sip_pubsub_body_generator *generator);
+AST_VECTOR(resources, const char *);
+
struct tree_node {
AST_VECTOR(, struct tree_node *) children;
char resource[0];
@@ -668,8 +670,21 @@
ast_free(node);
}
+static int have_visited(const char *resource, struct resources *visited)
+{
+ int i;
+
+ for (i = 0; i < AST_VECTOR_SIZE(visited); ++i) {
+ if (!strcmp(resource, AST_VECTOR_GET(visited, i))) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
static void recurse_list(struct ast_sip_endpoint *endpoint, const struct ast_sip_subscription_handler *handler,
- struct resource_list *list, struct tree_node *parent)
+ struct resource_list *list, struct tree_node *parent, struct resources *visited)
{
int i;
@@ -677,6 +692,10 @@
struct tree_node *current;
struct resource_list *child_list;
const char *resource = AST_VECTOR_GET(&list->items, i);
+
+ if (have_visited(resource, visited)) {
+ continue;
+ }
child_list = retrieve_resource_list(resource);
if (!child_list) {
@@ -687,7 +706,7 @@
}
} else {
current = tree_node_alloc(resource);
- recurse_list(endpoint, handler, child_list, current);
+ recurse_list(endpoint, handler, child_list, current, visited);
if (AST_VECTOR_SIZE(¤t->children) > 0) {
AST_VECTOR_APPEND(&parent->children, current);
} else {
@@ -710,19 +729,20 @@
const char *resource, struct resource_tree *tree)
{
struct resource_list *list;
+ struct resources visited;
+
+ list = retrieve_resource_list(resource);
+
+ tree->root = tree_node_alloc(resource);
/* Simple shortcut in case the requested resource is not a list */
- list = retrieve_resource_list(resource);
if (!list) {
return handler->notifier->new_subscribe(endpoint, resource);
}
- /* XXX This initial effort is a naive approach that assumes there are
- * no loops in the lists and no duplicated resources. This will have
- * to be addressed later
- */
- tree->root = tree_node_alloc(resource);
- recurse_list(endpoint, handler, list, tree->root);
+ AST_VECTOR_INIT(&visited, AST_VECTOR_SIZE(&list->items));
+ recurse_list(endpoint, handler, list, tree->root, &visited);
+ AST_VECTOR_FREE(&visited);
if (AST_VECTOR_SIZE(&tree->root->children) > 0) {
return 200;
@@ -954,10 +974,6 @@
pubsub_module.id, MOD_DATA_PERSISTENCE, persistence);
memset(&tree, 0, sizeof(tree));
- /* XXX This section needs to use the same bit of logic as is used when
- * processing a new inbound subscription so that a subscription tree
- * is created
- */
resp = build_resource_tree(endpoint, handler, resource, &tree);
if (PJSIP_IS_STATUS_IN_CLASS(resp, 200)) {
sub = create_subscription_tree(handler, endpoint, &rdata, resource, generator, &tree);
More information about the svn-commits
mailing list