ID:2028736
 
Applies to:Dream Daemon
Status: Open

Issue hasn't been assigned a status value.
Basically, rather then have for(var/thing in list) copy at the start of the loop, you could have it mark the loop as being looped thru, and the first time something goes to modify it, it copys the list for the for loop.

This way cases where copying the list isn't needed don't incur that overhead.

how this would work, is the list would have a pointer to a pointer pointing to the pointer the for loop is using to loop thru the array, and list write code would just have to copy the list, and then change that pointer's pointer to point to the new list. then unset the pointer to a pointer on the list as its not being used in a forloop anymore.


forloop unsets this pointer to a pointer when it exits, or if it's already unset, garbage collects the list it was using, as it's a copy.

Inner forloops on the same list would just copy, set the pointer's pointer to the copy, then set the pointer to point to it's new pointer. =P

example c code (my c is a bit rusty, but it should give you an idea of what i'm suggesting)

sturct _list {
c_pointer ** activeforloop = 0;
/*normal stuff*/

} List;

void writetolist(/*args*/) {
if (list->activeforloop) { //list is in a loop, copy it.
List * newlist = copylist(list); //copylist would have to not preserve activeforloop
*(list->activeforloop) = newlist;
list->activeforloop = 0;
}
/*normal stuff*/
}

void runforloop(/*args*/) {
int[] * currentlist = list;
if (list->activeforloop) {
List * newlist = copylist(list);
*(list->activeforloop) = newlist;
}

list->activeforloop = &currentlist;

for (int i = 0, i < currentlist->len, i++)
dostuff(currentlist->contents[i]);

//list is a copy, free it
if (!currentlist->activeforloop || currentlist->activeforloop != &currentlist)
free(currentlist);
else
currentlist->activeforloop = 0;

}


basically, no overhead from checking for the copy'ed list. we just allow external code to edit our pointer (what could go wrong =P)

That might not work fully, but i trust you could find a way to make it work.
This is fairly difficult, especially when looping through view/range which uses a built-in temporary list.