Hashes in macroscheduler

Technical support and scripting issues

Moderators: Dorian (MJT support), JRL

Post Reply
mrh32
Newbie
Posts: 13
Joined: Thu Feb 20, 2003 3:06 pm

Hashes in macroscheduler

Post by mrh32 » Thu Mar 13, 2003 6:41 pm

Hi again, I really like macro scheduler and have been messing around the past few days trying to implement hash tables in it. I have pretty much done it, except for one slight problem, I can't doubly dereference a variable (I'm sure that this is not the proper term, so I'll give an example below so you can see what I'm talking about). Basically when I say doubly derefence I mean using 2 sets of %'s around a variable whose name is also the name of another variable.

let>hashKey=456464
let>countName=hashCount%hashKey%
let>%countName%=1
let>vals%hashKey%[%countName%]=189
//the above line is the line with the problem, I don't want to set vals456464[hashCount456464]
//to 189 I want to set vals456464[1] to 189. I also tried this line
//let>vals%hashKey%[%%countName%%]=189
//but this just sets vals456464[%%countName%%] to 189
let>vals%hashKey%[2]=289
let>arrayPos=1
let>tempx=vals%hashKey%[%arrayPos%]
let>arrayPos=2
let>tempy=vals%hashKey%[%arrayPos%]
message>%tempx% should be 189 and %tempy% should be 289

I've tried to achieve hashing a few other ways; visual basic, and ini files (too slow), and using gotos and labels (quite fast but takes up many lines of code, and if you pass in an unknown key your program dies). If you have a fast way of not dieing when your goto goes to a non existant label (some way of catching the error before the system handles it) or a way of doubley de-referencing as described above, or have already found another fast way to implement hashes in macroscheduler, I'm all ears. Any help you can provide would be appreciated.

--Matt

P.S. This is the hash code I wrote up, I think it would work if I could doubley dereference stuff, but I'm not sure


//give a key and a value to be added to the hash
//takes in hashKey, hashValX and hashValY
SRT>addToHash
//first check to see if the key already exists in the hash
let>hashTemp=%%hashKey%%
midstr>hashTemp,1,1,hashDef
let>hashPercent=%
if>hashDef=hashPercent,AddHashKey,AddDataToHashKey
label>AddHashKey
//increment key count so you know there is another value in the hash
add>hashKeyCount,1
//point the key's value to keyCount so when you access it later it will access the correct value in the array
let>%hashKey%=hashKeyCount
//initialize this particular key's count to 0
let>count%hashKey%=0
//let the hashKeys array point to this key's array
let>hashKeys[%hashKeyCount%]=vals%hashKey%
label>AddDataToHashKey
//increment this hash's count variable and add the x and y variables to it
add>count%hashKey%,1
let>vals%hashKey%[count%hashKey%]=hashValX
add>count%hashKey%,1
let>vals%hashKey%[count%hashKey%]=hashValY
End>addToHash

//This function takes a hashKey and messages the user with all the value pairs stored under that hashKey
SRT>getFromHash
let>arrayPos=1
let>msg=The data pairs of key %hashKey% are
let>subHashArray=hashKeys[%%hashKey%%]
midstr>subHashArray,1,1,hashDef
//if the hashKey hasn't been defined then subHashArray should just be a string starting with hashKeys
//if you wanted to store strings starting with h in the hash this would have to be changed
if>hashDef=h,undefinedHashKey,definedHashKey
label>undefinedHashKey
let>msg=The key %hashKey% is currently undefined in the hash
goto>endGetFromHash
label>definedHashKey
let>tempX=subHashArray[arrayPos]
add>arrayPos,1
let>tempY=subHashArray[arrayPos]
concat>msg, %arrayPos%:%tempX% %tempY%
add>arrayPos,1
let>temp=count%hashKey%
if>arrayPos>%%temp%%,endGetFromHash,definedHashKey
label>endGetFromHash
messagemodal>%msg%
End>getFromHash

User avatar
Captive
Macro Veteran
Posts: 213
Joined: Sun Oct 20, 2002 8:37 pm
Location: Colorado, USA

Post by Captive » Sun Mar 23, 2003 7:38 pm

Hi. I've spent a fair amount of time looking at your code, and then playing with methods to do what you want.

Unfortunately, I haven't written a working "addToHash" type routine (and I don't really intend to at this point), but hopefully I can give you some pointers that will assist you in finishing yours.

I'm going to be quoting a lot of your previous post, then responding to it.
and have been messing around the past few days trying to implement hash tables in it.
I understand this to be associative arrays. For example, we have the key "Steve", then an associated value to that of "20" (which might mean Steve is 20).
I can't doubly dereference a variable (I'm sure that this is not the proper term, so I'll give an example below so you can see what I'm talking about). Basically when I say doubly derefence I mean using 2 sets of %'s around a variable whose name is also the name of another variable.
let>hashKey=456464
let>countName=hashCount%hashKey%
let>%countName%=1
let>vals%hashKey%[%countName%]=189
You've defined the value of "countName" twice - the second line is not redundant, and also you don't need the %'s in the 3rd line.
Other than that, the above will work

Let>hashKey=456464
Let>countName=1
Let>vals%hashKey%[%countName%]=189

This does: vals456464[1]=189
//the above line is the line with the problem, I don't want to set
//vals456464[hashCount456464] to 189
//I want to set vals456464[1] to 189. I also tried this line
//let>vals%hashKey%[%%countName%%]=189
//but this just sets vals456464[%%countName%%] to 189
Yeah, your "let>countName=hashCount%hashKey%" was the culprit then.

After decyphering the method you're using of storing key/value pairs, I have some suggestions/comments.

The way you're going about it stores key/value pairs like this:
(Assume we're working on array #78, called vals78[xxx])
Let>hashKeys[78]=vals78
Let>count78=1
Let>vals78[count1]=Steve
Let>count78=2
Let>vals78[count2]=20

I found your naming slightly disorganised. Take a look at this example. Note that the 'Pair' could be any name... If you Let>c=78, you can use it as Pair%c%[count]=2 (etc).

Storing the key/value pairs of names and ages:

Let>Pair[count]=2
Let>Pair[key1]=Steve
Let>Pair[value1]=20
Let>Pair[key2]=David
Let>Pair[value2]=33

Let>Pushups[20]=32
Let>Pushups[33]=28

Let>i=0
Repeat>i
Add>i,1
Let>myKey=Pair[key%i%]
Let>myValue=Pair[value%i%]
Let>myPCount=Pushups[%myValue%]
MessageModal>Pair #%i%%CRLF%%myKey% ==> %myValue%%CRLF%%myKey% is %myValue% and has to do %myPCount% pushups.
Until>i,Pair[count]

In this example: %myValue% becomes the name of another variable (Pushups[20] for example, and it appears to evaluate just fine)

There are two significant potential problems I see here.
1) When a value is erased (for example: the 3rd in 10 entries), the rest of the key/value pairs have to be moved around.

2) I don't think MSched will free the memory when you 'blank' (erase) a key/pair value. So if you make 50 arrays, each having 100 entries - then you erase them all - those variables will still exist, as far as I am aware (they'll just be blank)
Marcus - if you're reading this, is there a way to 'undefine' a variable or array entry?
I've already requested for a function to see if a variable was defined or not - this would solve your midstring % comparison' problem. I can't find it in the history or help file now, so maybe it was just a dream. I now think a similar procedure that undefines variables would be good too.

Bottom line, it's possible to create hash tables, and even possible to create SRT's that work on them. At this time in MSched, it would be *very* difficult to manage them effeciently - especially when deleting entries.

Post Reply
Sign up to our newsletter for free automation tips, tricks & discounts