|
Joined: Jan 2004
Posts: 162
Vogon poet
|
Vogon poet
Joined: Jan 2004
Posts: 162 |
I created a bunch of array snippets that used hash tables to store sorted information. Whilst they are unsorted by nature, if you just use numbers as key names then you can manage the sort yourself. For example, if you were to sort this data alphabetically: z b d h j e, it would become: b d e h j z, you could then add each letter to the hash table with a number as key: hadd -m table 1 b
hadd -m table 2 d
hadd -m table 3 e
hadd -m table 4 h
hadd -m table 5 j
hadd -m table 6 z Then: echo -a $hget(table,1) = b
echo -a $hget(table,2) = d
echo -a $hget(table,3) = e
echo -a $hget(table,4) = h
echo -a $hget(table,5) = j
echo -a $hget(table,6) = z And there you have it, sorted hash tables ![laugh laugh](/images/graemlins/mirc/laugh.gif) The only thing you need to keep in mind when using this method is that if you were to delete an item you'd have to reshuffle every item after that position so there are no gaps, unless you come up with a decent method to iterate through the table until all items have been found even if there are gaps. This is where the main overhead comes in, it's quite slow to reshuffle 1,000+ items. In the past I've seen similar ideas. I know most problems have a solution. But I'll recap what I said: My interest in this * Error creating window (and * Error creating dialog) is because in ran in both, the first when having alot connections/channels and the latter when I try to test my script between two mIRC instances (it has a kind of remote control through sockets, where remote configuration files are sent and loaded in quite big dialogs). Beside this, my script uses an amount custom windows for script configuration data, but that amount doesn't increase with the amount irc connections so it's not a problem as worse as the irc windows. I found the way custom windows can be used very handy. They keep their order by themselve, they are fast and various powerful commands work on them, /filter can be used to sort on token position, $fline() is handy to find a line with a certain token on a certain position, and several other commands provide in add/delete/insert/etc of one single line. So, for every sort of task, there's a choice. The big 'but' of this is that the window-being of this storage solution is actually an unwanted side-effect. mIRC should have a similar memory structure, maybe in the form of an array where the 'slot'-names are 'behind the scenes', leaving only the value part. I don't know if such structure already exists under some other name. And of course, also commands similar to what now is available for custom windows. Clickhere once said that a dll could mimic this easily and wouldn't be hard to write, but I'm not a big fan of using dll's for such script core functionality, they create a heavy dependency on a completely third party-'plugin' to a main commercial application. If for any reason the dll becomes unusable then the mIRC script completely relying on it follows it into the grave. Back to the question I had, suppose this * Error creating window stops a channel window from being created, could it be so programmed that mIRC can be told to not create a window (thus on purpose)? Because that would allow scripts to be on alot networks/channels, unlimited by this resource problem, while still be able to use all what mIRC has available as functions, because the only alternative is to use socket connections to the irc servers, inflicting the need to do -everything- in script, from protocol parsing till IAL, notify, etc. The question is if this is realistic, as is, how much are mIRC's functions dependent on the existence of the window.
|
|
|
|
Joined: Jan 2004
Posts: 162
Vogon poet
|
Vogon poet
Joined: Jan 2004
Posts: 162 |
Wow someone's getting defensive. I started to talk to you like you talk to me. Like it? To be fair, I didn't *ignore* anything. I ported your alias *command for command* to hash tables. It works exactly the same as your code, does exactly the same thing, and it's faster. So are you going to admit it's faster yet or are you going to cry about a bad experience at McDonalds? And your point is? That I'm still right? Thanks. Sorry when I tested the code I stepped off the "all computers run at exactly the same speed" planet. I'm not sure who "confirmed" this (I don't see anyone confirming it here).. Hash tables items are not ordered in memory, yes, but if you practice what you preach and look at the code you'll see that my key names are in fact unique numerical indexes. Do you know what unique numerical indexes do when used as keys? They maintain order. $hget(yay,500) would get line 500, $hget(yay,200) would get line 200, etc.. I'm assuming you didn't actually understand this fact, or you wouldn't have made the above statement. To clarify, my hash table data *is* ordered, just not in your ram. Do you still think I'm wrong? Huh? I didn't assume anything. I'm responding to your incorrect statement based on what you said here, namely: This is simply wrong. First of all, they're not considered "false positives" if you incorrectly use a '*' as a literal when you know mIRC will parse it as a wildcard. That's called: using a command incorrectly. If you want to search for a line that contains '*' you use a regular expression match and escape it so it's not treated in a special manner. What exactly was I assuming here? I'm merely telling you that you CAN use /filter to match literal '*'s. Are you still saying you can't? Do you still think I'm wrong? You don't seem to enjoy factual proof. I'm giving you working code with improved benchmark results that you yourself corroborate and for some reason my giving of this information makes you call me a "politician", which makes no sense to me. Rather than focusing on why my facts may be invalid you're more interested in horrible analogies and trying to insult me by calling me names. Real classy. I'm not sure how else I can convince you...
I throwed all your text together on purpose. I already told you: I'm not using regular expressions. For the rest, arguev0 further with yourself about usage of terms and statements and blah blah blah.
|
|
|
|
Joined: Sep 2005
Posts: 2,881
Hoopy frood
|
Hoopy frood
Joined: Sep 2005
Posts: 2,881 |
I'd love to see an array structure with similar implementation to hashtables.
/amake <name> /aadd [-m] <name> [index] <data> ** if [index] is specified it will overwrite that index. /adel <name> <index> /ainsert [-m] <name> <index> <data> ** [-m] means the same as it does with hashtables. Create array if it doesn't already exist. /afree <name> $aget(name,index) $afind(name,text[,nwWrR])[.data]
With an array being a list that maintains order then obviously insert/overwrite commands would be beneficial too. Then a switch for /filter to act on arrays would be good.
|
|
|
|
Joined: Oct 2003
Posts: 3,918
Hoopy frood
|
Hoopy frood
Joined: Oct 2003
Posts: 3,918 |
"I'm not using regular expressions"?
What is that, some kind of protest?
No mommy, I refuse to eat my lunch!
The fact that you're making your own life miserable is completely beside the point that it's possible.
- argv[0] on EFnet #mIRC - "Life is a pointer to an integer without a cast"
|
|
|
|
Joined: Jul 2006
Posts: 4,180
Hoopy frood
|
Hoopy frood
Joined: Jul 2006
Posts: 4,180 |
I'd love to see an array structure with similar implementation to hashtables.
/amake <name> /aadd [-m] <name> [index] <data> ** if [index] is specified it will overwrite that index. /adel <name> <index> /ainsert [-m] <name> <index> <data> ** [-m] means the same as it does with hashtables. Create array if it doesn't already exist. /afree <name> $aget(name,index) $afind(name,text[,nwWrR])[.data]
With an array being a list that maintains order then obviously insert/overwrite commands would be beneficial too. Then a switch for /filter to act on arrays would be good. I've just seen your ideas, what's the difference with what you suggest and hash table method ? I've don't see any difference, it does exactly the same thing, just have to suggest /hins [-m] <name> <item> <data>, assuming that you're using number as item (would be a nice idea). However, the switch for /filter could be very useful, how you think it would work ? I have an idea, but just to see if it's the same, this could be very very useful as well ![smile smile](/images/graemlins/mirc/smile.gif)
#mircscripting @ irc.swiftirc.net == the best mIRC help channel
|
|
|
|
Joined: Dec 2002
Posts: 2,962
Hoopy frood
|
Hoopy frood
Joined: Dec 2002
Posts: 2,962 |
An array is an ordered structure where each item is indexed by an integer (ie. its position within the array), a hash table is an unordered structure where each item is indexed by a key. The majority of the commands and identifiers associated with each might look the same but the situations for which they are suitable differ considerably.
Spelling mistakes, grammatical errors, and stupid comments are intentional.
|
|
|
|
Joined: Jul 2006
Posts: 4,180
Hoopy frood
|
Hoopy frood
Joined: Jul 2006
Posts: 4,180 |
a hash table is an unordered structure where each item is indexed by a key Sure, but if each item is a number, then it's ordered, what would be the difference between using an hash table with number index for each item name and hixxy's feature ?
#mircscripting @ irc.swiftirc.net == the best mIRC help channel
|
|
|
|
Joined: Apr 2004
Posts: 759
Hoopy frood
|
Hoopy frood
Joined: Apr 2004
Posts: 759 |
With hash tables adding them in order does not mean their stored sorted numerically based on their key value as well. Their stored sorted on their hashes. The following code demonstrates this:
//var %x = 1 | while (%x < 100) { hadd -m th %x hello %x | inc %x } | hdel th 50 | echo -a $hget(th,50) => $hget(th,2).item | hfree th
$hget(th,50) does not echt hello 51 it just doesn't excist, In arrays slicing a piece out (hdel) would bump the rest back up. $hget(th,2).item does not return 2 but 4. This is the major advantage of non-ascociative arrays over hashtables. I'd love to see native array support although i rather see a pop/push/slice etc terminology implemented over hixxy's suggestion.
$maybe
|
|
|
|
Joined: Jul 2006
Posts: 4,180
Hoopy frood
|
Hoopy frood
Joined: Jul 2006
Posts: 4,180 |
I know how hash table work, and I was needed some little clarification about what hixxy suggested, you've done this job thanks, and then indeed, it would be very useful, should be added as a feature suggestion if it's not already there.
#mircscripting @ irc.swiftirc.net == the best mIRC help channel
|
|
|
|
Joined: Oct 2003
Posts: 3,918
Hoopy frood
|
Hoopy frood
Joined: Oct 2003
Posts: 3,918 |
As people pointed out, using indexed values for keys does not create an internally ordered structure, though the usage of the hash table API where keys are ordered integers *does* result in an ordered structure for all intensive purposes. On one hand, I see why certain nitpickers might care about the internal implementations that mIRC might use for efficiency. On the other hand, the *majority* of users should not be concerned with implementation, as that's Khaled's job... the fact that you can do: hadd tab 2 item | $hget(tab,2) => item means it's functionality equivalent to an array API, so I don't see the issue from a superficial standpoint.
Was this suggested specifically for efficiency reasons, or for functionality? If it really is an efficiency thing, would this really make a big difference? I doubt the bottleneck is the hash function, and I'd bet there would be no noticeable performance improvement, though benchmarks would be interesting to see.
The most constructive thing I could suggest is to add a switch (-i?) on /hmake to index instead of hash. This would mean keys would need to be numeric but it would allow mIRC to implement the structure internally as an array while keeping the user level API the same. The benefit here would be not having to introduce an equivalent set of commands/identifiers that have the same functional behaiour.
- argv[0] on EFnet #mIRC - "Life is a pointer to an integer without a cast"
|
|
|
|
Joined: Dec 2002
Posts: 2,962
Hoopy frood
|
Hoopy frood
Joined: Dec 2002
Posts: 2,962 |
Hash tables aren't functionally equivalent even if you use numeric keys. Deletion may be equivalent as a byproduct of mIRC's implementation (I haven't checked) but insertion certainly won't be possible without manually shifting all higher indexes - now that definitely would result in unacceptable performance.
The hash table API also isn't very descriptive when applied to arrays - for example would /hadd insert a new item at a given index or overwrite it? Adding support for slicing in relevant commands would add an unnecessary layer of complexity to the /h* commands making them quite different depending on what kind of 'hash table' was being used, not to mention there would also (presumably) be additional commands for arrays that would have no relevance to hash tables (eg. sorting). All in all having two different concepts sharing a set of commands would be extremely messy and would only confound most scripters.
Spelling mistakes, grammatical errors, and stupid comments are intentional.
|
|
|
|
Joined: Apr 2004
Posts: 759
Hoopy frood
|
Hoopy frood
Joined: Apr 2004
Posts: 759 |
Associative arrays map very wel to hash tables. Pure arrays don't, i'm with starbucks_mafia on this one. (Deletion is not a byproduct either see code i posted above, it will create unreferencable gaps.) the fact that you can do: hadd tab 2 item | $hget(tab,2) => item means it's functionality equivalent to an array API, so I don't see the issue from a superficial standpoint.
This holds truth provided you dont insert and delete items of the 'stack'. Pure arrays will be used as stacks where inserting and/or deleting items will re-order the stack accordingly automatically so they're always in a loop safe state. In short hash table is great for associative data but a mess to loop through (Since gaps CAN appear). Pure arrays have nothing to do with associative data but are excellent to loop trough. Since they are not the same thing i dont think if arrays are ever implemented that they should share the same terminology as the hash table commands let alone share the commands ![smile smile](/images/graemlins/mirc/smile.gif)
Last edited by Mpdreamz; 11/02/09 05:36 PM.
$maybe
|
|
|
|
Joined: Sep 2005
Posts: 2,881
Hoopy frood
|
Hoopy frood
Joined: Sep 2005
Posts: 2,881 |
alias fakearray {
hadd -m array 1 a
hadd -m array 2 b
hadd -m array 3 c
hdel array 2
var %i = 1
while ($hget(array,%i) != $null) {
echo -a $v1
inc %i
}
} Here is one of the major problems with using a hash table to simulate an array. The only way to fix the problem with the gaps, is to shift all items past the point of deletion down. This takes some amount of time on big tables: I know because I wrote a script that for all intents and purposes lets you create perfect arrays using hash tables. I don't have the full script anymore, but I've whipped up a little test script to give you some idea of how slow it is to shift down entries in a hash table when you need to delete a numerical index. alias -l create {
var %i = $2
while (%i) {
hadd -m $1 %i %i
dec %i
}
}
alias -l delete {
hdel array $2
var %i = $2 + 1
while ($hget($1,%i) != $null) {
hadd -m $1 $calc(%i - 1) $v1
inc %i
}
hdel $1 $hget($1,0).item
}
alias testspeed {
var %ticks = $ticks
create array 3000
var %i = 1500, %j = 1400
while (%i > %j) {
delete array %i
dec %i
}
hfree array
echo -a $calc($ticks - %ticks) ms.
} This creates a hash table containing 3,000 items, then it deletes 100 of those items from somewhere in the middle of the table. Each time it does this, it shifts all of the indexes above that down, so that the "array" maintains order (and can still be referred to as $hget(array,N)). On my 3ghz dual core CPU this takes around 4.6 seconds to execute, and it's not even an unrealistic example. Having arrays built in would be much more efficient and also convenient.
|
|
|
|
|