Dict issue, help please!

arockmez's icon

I have a dictionary called session_tokens like this:

{
    "current_objects" :     {
        "first" :         {
            "type" : "nlayer"
        }
,
        "second" :         {
            "type" : "nlayer"
        }
,
        "third" :         {
            "type" : "nlayer"
        }

    }

}

Every element inside current_objects represents a token inside a system, so this way i can handle them for other purposes, the thing that matters is that first, second and third are the name of the tokens.

I created a function EXECUTEORDER66 (yes, i’m a SW fan) that destroys all tokens at the same time and delete them from dictionary session_tokens, so after EXECUTEORDER66current_objects should be empty.

EXECUTEORDER66 is this function:

function EXECUTEORDER66
{
    targets = element_iter("current_objects");
                

    if(targets)

        {
            for(i=0;i

targets is and array with current tokens, so:targets[0] = firsttargets[1] = secondtargets[2] = third

it's gotten from the element_iter function, which is this:

function element_iter(id)
    {
        dict = new Dict("session_tokens");
        
        if(dict.contains(id))
            {
                current_elements = dict.get(id);
                elements = current_elements.getkeys();
                
                    if(elements instanceof Array)
                            {
                                return elements;
                            }
                    else if ((typeof elements) == "string")
                        {
                            elements = [elements]; //This transforms the string element in a single element array
                            return elements;
                        
                    else
                        {
                            return null;
                        }
            }
        else
            {
                return null;
            }

    }

If there’s no token current_objects should be empty and targets will be null because element_iter returns null in that case. Everything up to this point is working fine.

Inside the for cycle i’m posting the current target to Max Window and then using whisper function. This functions deletes a token from the system and removes it from the dictionary. Whisper alone is working OK for a single call, but when i use EXECUTEORDER66 the i inside the cycle seems to change even then it hasn’t complete a single loop:

The first post(targets[i]) results in “first” which is fine, then the “first” token is deleted correctly but post(targets[i]) after whisper function returns “third” and not “first” again like i’m expecting.
Then the cycle stops and never perform a loop again, like i think it should do because the array has 3 elements.

I think my problem is related with dictionaries because im rookie with them.

Thank you in advance!

do.while's icon

it might be that u are making your i global variable . please use var in function body to make i hoisted there . and lets see if that helps

arockmez's icon

Oh, thank you, you were completely right....such i lame error (this happens when you spend a lot of time with merciful languages like PHP!) i'll have to go over js var scope and de-globalize my whole script if necessary

arockmez's icon

another question...is really harmful to work with the dict directly inside js if the dict is created (and embedded) outside js? i have read it twice i think, but still don't get why...sometimes it need just to read content of the dict, but sometimes i need to edit it, so i think is this second case, there's no other way than working with the dict directly and then freepeer() it

do.while's icon

yeah JS is dynamic in its nature in too many fields as this which uve experienced . it should use for loop scope or at least function scope but not global scope . this is crazy , we must remember it :/

freepeer() is definitely your friend when you make a lot of IO operations on referenced instance ... if two applications (or objects) uses the same instance to make their tasks , there might be some thread safetiness issue , or owner issue . U should reference Dict and freepeer() it when not needed .

If u want to keep reference in your code then perhaps the best option to keep safetiness would be cloning your Dict with clone procedure . Make use of it and clone it back to main instance .

Dont afraid of this approach , its a good habit not a hack .

Let me know if i explained it clearly enough.

arockmez's icon

Thank you again. It's clear enough, but what i don't get yet, if is there's another advantage about using a clone of every Dict while operating...i mean...suppose you are the god of codelines and the code itself works perfectly and Dict never mess with other Dict ...in this case, there would be a huge difference between working with real Dict instead of cloned one? maybe speed, or another thing than safety?

do.while's icon

If u will be using Dict just inside your JS , and only there , then honestly u dont need to care for cloning and even freepeer()ing . Ive been testing it all ,and no issues were met . But i meet issues while Dict has been shared across many applications , or even across few JS objects .

If you will be forcing data in and out constantly, cloning your dict will make these tasks at first safe , then fast . As your main Dict instance will be referenced two times only (clone in , clone out) , you will make your tasks on separated data without interupting Dict's thread when some other conditions might want to access its data too . You will gain some efficiency . I think that cloning in and out is going on the memory pointers under the hood , so the overhead is minimized compared to copying data by data itself . I can measure it if u want . But i would not care until efficiency really drops .Actually ive noticed gain of efficiency , i really needed it , so u can trust me .

To be more clear . If you do retrieve and store data in Dict within more than one place , clone it ! . if u do your IO in one place , and retrieving its content in another , u can live with freepeer() all the way though .

arockmez's icon

That's clear enough for me...i didn't understand the logic of cloning dicts until you mentioned the access by many instances, thank you again for the explanation!

do.while's icon

just one thing . Im not told about it all . Ive studied SDK (where special care is required) at the time and concluded it all through additional experiments as i had issues with data flow and responsiveness . Since im treating my assumptions as valid , im not encountering any issues anymore . So that might be a good bet if i can put it that way.

arockmez's icon

Thanks DO...WHILE i'm making the same assumption and everything is working like a charm :)

Emmanuel Jourdan's icon

You shouldn't have to clone it. Once you get a reference on a dict (var mydict = new Dict("abc");) it increments the reference count of that "abc" dict (and decrement the reference count when it's no longer used). The only reason to clone it would if the data in your dict changes and you want to grab a specific moment.

do.while's icon

Hi !
what if two objects changes and retrieves data ? what happened to me -> random freezes , ui not responsive for a IO to/from dict process . Since i do clone it in and back , nothing like this happened anymore .

reference is one thing ,but what happen to dict is another . no ? threads , owner ?
at least it puts me in a safe place when i had to make a lot of changes in dict while other object tries to look at some of these (or change some desired portion) on its own time (midi event) . So i had to introduce cloning in the most intense part .

Emmanuel Jourdan's icon

dict is thread safe, unless proved otherwise (if you have some specific problem feel free to send them to support) ;-) The structure behind dict is the dictionary which uses both linklist and hashtable, even when you do a clone the dictionary will be locked during the cloning period.

arockmez's icon

Thank you EMMANUEL JOURDAN...both of you have been so helpful understanding dicts