[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