[asterisk-commits] akshayb: branch akshayb/ao2_containers r274091 - /team/akshayb/ao2_containers...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jul 6 08:36:08 CDT 2010


Author: akshayb
Date: Tue Jul  6 08:36:03 2010
New Revision: 274091

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=274091
Log:
alpha1 submit

Modified:
    team/akshayb/ao2_containers/main/astobj2_btree.c
    team/akshayb/ao2_containers/main/btree.c

Modified: team/akshayb/ao2_containers/main/astobj2_btree.c
URL: http://svnview.digium.com/svn/asterisk/team/akshayb/ao2_containers/main/astobj2_btree.c?view=diff&rev=274091&r1=274090&r2=274091
==============================================================================
--- team/akshayb/ao2_containers/main/astobj2_btree.c (original)
+++ team/akshayb/ao2_containers/main/astobj2_btree.c Tue Jul  6 08:36:03 2010
@@ -191,108 +191,13 @@
 		}
 	}
 
-static void *internal_ao2_callback(struct ao2_container *c,
-				   const enum search_flags flags, void *cb_fn, void *arg, void *data, enum ao2_callback_type type,
-				   char *tag, char *file, int line, const char *funcname)
-{
-	int i, start, last;	/* search boundaries */
-	void *ret = NULL;
-	ao2_callback_fn *cb_default = NULL;
-	ao2_callback_data_fn *cb_withdata = NULL;
-	struct ao2_container *multi_container = NULL;
-	struct ao2_iterator *multi_iterator = NULL;
-
-	if (INTERNAL_OBJ(c) == NULL)	/* safety check on the argument */
-		return NULL;
-
-	/*
-	 * This logic is used so we can support OBJ_MULTIPLE with OBJ_NODATA
-	 * turned off.  This if statement checks for the special condition
-	 * where multiple items may need to be returned.
-	 */
-	if ((flags & (OBJ_MULTIPLE | OBJ_NODATA)) == OBJ_MULTIPLE) {
-		/* we need to return an ao2_iterator with the results,
-		 * as there could be more than one. the iterator will
-		 * hold the only reference to a container that has all the
-		 * matching objects linked into it, so when the iterator
-		 * is destroyed, the container will be automatically
-		 * destroyed as well.
-		 */
-		if (!(multi_container = __ao2_container_alloc(1, NULL, NULL))) {
-			return NULL;
-		}
-// This part dosen't needs to be corrected as, it will be automatically corrected once we correct the ao2_iterator.
-		if (!(multi_iterator = ast_calloc(1, sizeof(*multi_iterator)))) {
-			ao2_ref(multi_container, -1);
-			return NULL;
-		}
-	}
-
-	/* override the match function if necessary */
-	if (cb_fn == NULL) { /* if NULL, match everything */
-		if (type == WITH_DATA) {
-			cb_withdata = cb_true_data;
-		} else {
-			cb_default = cb_true;
-		}
-	} else {
-		/* We do this here to avoid the per object casting penalty (even though
-		   that is probably optimized away anyway). */
-		if (type == WITH_DATA) {
-			cb_withdata = cb_fn;
-		} else {
-			cb_default = cb_fn;
-		}
-	}
-
-	/*
-	 * XXX this can be optimized.
-	 * If we have a hash function and lookup by pointer,
-	 * run the hash function. Otherwise, scan the whole container
-	 * (this only for the time being. We need to optimize this.)
-	 */
-	if ((flags & OBJ_POINTER))	/* we know hash can handle this case */
-		start = i = c->var.hash_fn(arg, flags & OBJ_POINTER) % c->var.n_buckets;
-	else			/* don't know, let's scan all buckets */
-		start = i = -1;		/* XXX this must be fixed later. */
-
-	/* determine the search boundaries: i..last-1 */
-	if (i < 0) {
-		start = i = 0;
-		last = c->var.n_buckets; // This get changed
-	} else if ((flags & OBJ_CONTINUE)) {
-		last = c->n_buckets;
-	} else {
-		last = i + 1;
-	}
-
-	ao2_lock(c);	/* avoid modifications to the content */
-
-	for (; i < last ; i++) {
-		/* scan the list with prev-cur pointers */
-		struct bucket_entry *cur;
-
-		AST_LIST_TRAVERSE_SAFE_BEGIN(&c->var.buckets[i], cur, entry) {
-			int match = (CMP_MATCH | CMP_STOP);
-
-			if (type == WITH_DATA) {
-				match &= cb_withdata(EXTERNAL_OBJ(cur->astobj), arg, data, flags);
-			} else {
-				match &= cb_default(EXTERNAL_OBJ(cur->astobj), arg, flags);
-			}
-
-			/* we found the object, performing operations according flags */
-			if (match == 0) {	/* no match, no stop, continue */
-				continue;
-			} else if (match == CMP_STOP) {	/* no match but stop, we are done */
-				i = last;
-				break;
-			}
+	ao2_lock(c);	/*avoid modifications to the content */
+	struct bt_key_val node_key_val =	btree_search (c, key);
 
 			/* we have a match (CMP_MATCH) here */
 			if (!(flags & OBJ_NODATA)) {	/* if must return the object, record the value */
 				/* it is important to handle this case before the unlink */
-				ret = EXTERNAL_OBJ(cur->astobj);
+				ret = EXTERNAL_OBJ(node_key_val->val);
 				if (!(flags & (OBJ_UNLINK | OBJ_MULTIPLE))) {
 					if (tag)
 						__ao2_ref_debug(ret, 1, tag, file, line, funcname);
@@ -313,48 +218,15 @@
 			if (flags & OBJ_UNLINK) {	/* must unlink */
 				/* we are going to modify the container, so update version */
 				ast_atomic_fetchadd_int(&c->version, 1);
-				AST_LIST_REMOVE_CURRENT(entry);
+				
+			//	AST_LIST_REMOVE_CURRENT(entry);
+				btree_delete_key(c->btree,c->btree->root, node_key_val->key)			
 				/* update number of elements */
 				ast_atomic_fetchadd_int(&c->elements, -1);
-
-				/* - When unlinking and not returning the result, (OBJ_NODATA), the ref from the container
-				 * must be decremented.
-				 * - When unlinking with OBJ_MULTIPLE the ref from the original container
-				 * must be decremented regardless if OBJ_NODATA is used. This is because the result is
-				 * returned in a new container that already holds its own ref for the object. If the ref
-				 * from the original container is not accounted for here a memory leak occurs. */
-				if (flags & (OBJ_NODATA | OBJ_MULTIPLE)) {
-					if (tag)
-						__ao2_ref_debug(EXTERNAL_OBJ(cur->astobj), -1, tag, file, line, funcname);
-					else
-						__ao2_ref(EXTERNAL_OBJ(cur->astobj), -1);
-				}
-				ast_free(cur);	/* free the link record */
 			}
-
-			if ((match & CMP_STOP) || !(flags & OBJ_MULTIPLE)) {
-				/* We found our only (or last) match, so force an exit from
-				   the outside loop. */
-				i = last;
-				break;
-			}
-		}
-		AST_LIST_TRAVERSE_SAFE_END;
-
-		if (ret) {
-			break;
-		}
-
-		if (i == c->var.n_buckets - 1 && (flags & OBJ_POINTER) && (flags & OBJ_CONTINUE)) {
-			/* Move to the beginning to ensure we check every bucket */
-			i = -1;
-			last = start;
-		}
-	}
-	ao2_unlock(c);
-
-	/* if multi_container was created, we are returning multiple objects */
-	if (multi_container != NULL) {
+			ao2_unlock(c);
+// Have to check the multi_container part
+if (multi_container != NULL) {
 		*multi_iterator = ao2_iterator_init(multi_container,
 						    AO2_ITERATOR_DONTLOCK | AO2_ITERATOR_UNLINK | AO2_ITERATOR_MALLOCD);
 		ao2_ref(multi_container, -1);
@@ -364,6 +236,9 @@
 	}
 }
 
+
+
+
 void *__ao2_callback_debug(struct ao2_container *c,
 			   const enum search_flags flags,
 			   ao2_callback_fn *cb_fn, void *arg,
@@ -404,3 +279,40 @@
 {
 	return __ao2_callback(c, flags, c->core.cmp_fn, arg);
 }
+
+// Writing code for ao2_iterator
+
+static void *internal_ao2_iterator_next(struct ao2_iterator *a, struct bucket_entry **q)
+{
+	int lim;
+	struct bucket_entry *p = NULL;
+	void *ret = NULL;
+
+	*q = NULL
+	if (INTERNAL_OBJ(a->c) == NULL)
+		return NULL;
+	if (!(a->flags & AO2_ITERATOR_DONTLOCK))
+		ao2_lock(a->c);
+	/* optimization. If the container is unchanged and
+	 * we have a pointer, try follow it
+	 */
+	if (a->c->version == a->c_version && (p = a->obj)) {
+		if ((p = AST_LIST_NEXT(p,entry)))
+			goto found;
+		/* nope, start from the next bucket */
+		a->bucket++;
+		a->version = 0;
+		a->obj = NULL;
+	}
+	lim = a->c->n_buckets;
+	
+	/* Browse the buckets array, moving to the next
+	 * buckets if we don't find the entry in the current one.
+	 * Stop when we find an element with version number greater
+	 * than the current one (we reset the version to 0 when we
+	 * switch buckets).
+	 */
+
+	for (; a->bucket < lim; a->bucket++, a->version = 0) {
+		/* scan the current bucket */
+		AST_

Modified: team/akshayb/ao2_containers/main/btree.c
URL: http://svnview.digium.com/svn/asterisk/team/akshayb/ao2_containers/main/btree.c?view=diff&rev=274091&r1=274090&r2=274091
==============================================================================
--- team/akshayb/ao2_containers/main/btree.c (original)
+++ team/akshayb/ao2_containers/main/btree.c Tue Jul  6 08:36:03 2010
@@ -734,8 +734,8 @@
 *       @param key Key of the node to be search
 *       @return The key-value pair
 */
-struct bt_key_val * btree_search(struct btree * btree,void * key) {
-
+struct bt_key_val * btree_search(struct container *c,void * key) {
+	struct btree btree = c->var.btree
 	struct bt_key_val * key_val = NULL;
 	struct node_pos kp = get_btree_node(btree,key);
 




More information about the asterisk-commits mailing list