summaryrefslogtreecommitdiffstats
path: root/common/collection/collection_iter.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/collection/collection_iter.c')
-rw-r--r--common/collection/collection_iter.c49
1 files changed, 44 insertions, 5 deletions
diff --git a/common/collection/collection_iter.c b/common/collection/collection_iter.c
index 4d7a90428..f66fc3085 100644
--- a/common/collection/collection_iter.c
+++ b/common/collection/collection_iter.c
@@ -87,6 +87,8 @@ int col_bind_iterator(struct collection_iterator **iterator,
iter->stack_depth = 0;
iter->item_level = 0;
iter->flags = mode_flags;
+ iter->pin_level = 0;
+ iter->can_break = 0;
TRACE_INFO_NUMBER("Iterator flags", iter->flags);
@@ -110,6 +112,7 @@ int col_bind_iterator(struct collection_iterator **iterator,
header = (struct collection_header *)ci->data;
header->reference_count++;
iter->top = ci;
+ iter->pin = ci;
*(iter->stack) = ci;
iter->stack_depth++;
@@ -213,17 +216,29 @@ int col_iterate_collection(struct collection_iterator *iterator,
TRACE_INFO_NUMBER("Stack depth:", iterator->stack_depth);
- /* Are we done? */
if (iterator->stack_depth == 0) {
- TRACE_FLOW_STRING("We are done.", "");
- *item = NULL;
- return EOK;
+ /* Re-init so if we continue looping we start over */
+ iterator->stack[0] = iterator->top;
+ iterator->stack_depth++;
+ iterator->item_level = 0;
}
/* Is current item available */
current = iterator->stack[iterator->stack_depth - 1];
iterator->item_level = iterator->stack_depth - 1;
+ /* Are we done? */
+ if (((iterator->stack_depth - 1) == iterator->pin_level) &&
+ (iterator->pin == current)) {
+ if (iterator->can_break) {
+ TRACE_FLOW_STRING("We are done.", "");
+ *item = NULL;
+ iterator->can_break = 0;
+ return EOK;
+ }
+ else iterator->can_break = 1;
+ }
+
/* We are not done so check if we have an item */
if (current != NULL) {
@@ -357,6 +372,30 @@ int col_iterate_collection(struct collection_iterator *iterator,
}
}
- TRACE_FLOW_STRING("iterate_collection", "Exit");
+ TRACE_FLOW_STRING("col_iterate_collection", "Exit");
return EOK;
}
+
+
+/* Pins down the iterator to loop around this point */
+void col_pin_iterator(struct collection_iterator *iterator)
+{
+ TRACE_FLOW_STRING("col_iterator_add_pin", "Entry");
+
+ while ((iterator->stack[iterator->stack_depth - 1] == NULL) &&
+ (iterator->stack_depth)) {
+ iterator->stack_depth--;
+ }
+
+ if (iterator->stack_depth == 0) {
+ iterator->pin = iterator->top;
+ iterator->pin_level = 0;
+ }
+ else {
+ iterator->pin = iterator->stack[iterator->stack_depth - 1];
+ iterator->pin_level = iterator->stack_depth - 1;
+ }
+ iterator->can_break = 0;
+
+ TRACE_FLOW_STRING("col_iterator_add_pin", "Exit");
+}