|
Joined: Apr 2006
Posts: 464
Fjord artisan
|
OP
Fjord artisan
Joined: Apr 2006
Posts: 464 |
I am currently working on a script that has to find information in a hash table, and retreive it. The table is set up like: <item> <data> The <data> part is one string, seperated by horizontal tabs, representing columns. Like: x ($chr9) y ($chr9) z ($chr9) name ($chr9) size ($chr9) score 1 ($chr9) 1 ($chr9) 1 ($chr9) blah ($chr9) 294 ($chr9) 25135 1 ($chr9) 1 ($chr9) 2 ($chr9) booh ($chr9) 954 ($chr9) 58462 ... and this continues for like another 4000 lines. Now I want to be able to retreive for example a top5 with the highest value in the size column or a top5 with highest value in score column. Is this possible? And if so, can anyone help me getting going with the (I think $hfind and $hget) commands? Your help is appreciated
|
|
|
|
Joined: Jan 2003
Posts: 3,012
Hoopy frood
|
Hoopy frood
Joined: Jan 2003
Posts: 3,012 |
The only ways I can see approaching this would be from a binary standpoint, i.e. go one by one and look for the top 5. No way of doing it with a mIRC cal, or so I'm aware. That being said, do you have a ceiling on the score or size values, or can they continue to grow? If you know the ceiling, go in reverse order (counting down) and look for the table entry with the highest value, then subtract one. Look for the next highest, etc. Keep a queue of 5 "tops", and display them. I'll see what i can do playing around with it. If anyone wants to play with it as well, here's a generator to give you something to work with:
alias pinfo {
var %tbl = pinfo, %entries = 100
if (!$hget(%tbl)) {
/hmake %tbl 10
var %p = 0, %tab = $chr(9)
while (%p < %entries) {
var %n = 0, %len = $rand(6,12)
while (%n < %len) {
var %name = $+(%name,$rand(a,z))
/inc %n
}
/hadd %tbl %p $+($rand(1,10),%tab,$rand(1,10),%tab,$rand(1,10),%tab,%name,%tab,$rand(1,1000),%tab,$rand(1,65535))
/unset %name
/inc %p
}
/echo -s Table %tbl created with %p entries
}
}
-KingTomato
|
|
|
|
Joined: Jan 2003
Posts: 3,012
Hoopy frood
|
Hoopy frood
Joined: Jan 2003
Posts: 3,012 |
alias pfind {
var %tbl = pinfo, %tsize = $hget(%tbl,0).item, %win = @pinfo_srt, %win2 = @pinf_srtd
; add to window
/window -h %win
/window -h %win2
var %p = 1
while (%p <= %tsize) {
/aline %win $+($hget(%tbl,%p).item,$chr(9),$hget(%tbl,$hget(%tbl,%p).item))
/inc %p
}
; sort
if ($1 == size) /filter -tuww 6 9 %win %win2
else if ($1 == score) /filter -tuww 7 9 %win %win2
; Output
var %lines = $line(%win2,0), %l = %lines - 5, %c = 1
if (%l < 0) var %l = 0
while (%lines > %l) {
/echo -s $+(%c,.) $line(%win2,%lines)
/inc %c
/dec %lines
}
/window -c %win
/window -c %win2
}
Nevermind /filter was just what i needed. Should work fine, and give you the results you want. You may even decide to make it call an alias, or reroute the information. As it is, change the /echo in the ; output section to do what you'd like. Also, change the %tbl variable to the name of your own table. [edit]If you want to sort by anything else (name maybe, or even descending) fool with the filters. These will give you descending sorts for either option:
; sort
if ($1 == size) /filter -tuww 6 9 %win %win2
else if ($1 == score) /filter -tuww 7 9 %win %win2
else if ($1 == sizedesc) /filter -etuww 6 9 %win %win2
else if ($1 == scoresesc) /filter -etuww 7 9 %win %win2
use /pfind <size|size desc|score|score desc>
-KingTomato
|
|
|
|
Joined: Apr 2006
Posts: 464
Fjord artisan
|
OP
Fjord artisan
Joined: Apr 2006
Posts: 464 |
OMG, it works! Alright, at the moment I have no idea how or why it works, but it definately does what I asked. I'll go check the code out Thx a lot KingTomato [Edit] This is really perfect. There are more fields indead that I might want to have the sorting on. I'll go play with it a bit. Thx again man.
Last edited by OrionsBelt; 29/05/06 08:49 PM.
|
|
|
|
Joined: Apr 2006
Posts: 464
Fjord artisan
|
OP
Fjord artisan
Joined: Apr 2006
Posts: 464 |
Hmm, one other problem I now get. The file contains a header, like file contents and stuff:
1. 1 HTTP/1.1 200 OK 2. 2 Date: Mon, 29 May 2006 20:06:06 GMT 3. 3 Server: Apache/2.0.54 4. 4 Last-Modified: Mon, 29 May 2006 20:02:01 GMT
Is there are way to get rid of this information? Perhaps by not inserting it in the table at the beginning already?
Is it possible to specify where to start when loading a file into a hash table? Like start from line 15 till the end of the file?
(Especially with the desc functions, these are playing up).
Last edited by OrionsBelt; 29/05/06 09:08 PM.
|
|
|
|
Joined: Jan 2003
Posts: 3,012
Hoopy frood
|
Hoopy frood
Joined: Jan 2003
Posts: 3,012 |
Either don't input it in to the table, or change the %p below the /window commands. I'm assuming you're readin this info off a web page, maybe just eliminate the reading of the header?
-KingTomato
|
|
|
|
Joined: Sep 2003
Posts: 4,230
Hoopy frood
|
Hoopy frood
Joined: Sep 2003
Posts: 4,230 |
Another way of doing it is to use HSAVE, as on tables of any size say the 4000 one he said he had, its much faster to output the hashtable to a file and sort it there. alias pfind2 {
var %tbl = pinfo
;
; save table (data only)
hsave -n %tbl temp.txt
;
; sort
if ($1 == size) { filter -ffctuen 5 9 temp.txt temp.txt }
elseif ($1 == score) { filter -ffctuen 6 9 temp.txt temp.txt }
elseif ($1 == sizedesc) { filter -ffctun 5 9 temp.txt temp.txt }
elseif ($1 == scoredesc) { filter -ffctun 6 9 temp.txt temp.txt }
else { return } | ; no valid sort directive
;
; Output for example
var %i = 1, %m = 5
while (%i <= %m) {
echo -s $+(%i,.) RAWinFILE = $read(temp.txt,nt,%i)
inc %i
}
echo -s
var %i = 1, %m = 5
while (%i <= %m) {
echo -s $+(%i,.) PROCESSED = item $hget(%tbl,$gettok($read(temp.txt,nt,%i),1,32)).item data $hget(%tbl,$gettok($read(temp.txt,nt,%i),1,32)).data
inc %i
}
echo -s
.remove temp.txt
} example /pfind2 score 1. RAWinFILE = 2431 2 <tab>1 <tab>4 <tab>pguyda <tab>915 <tab>65534 2. RAWinFILE = 3683 9 <tab>3 <tab>8 <tab>cnitrkds <tab>557 <tab>65529 3. RAWinFILE = 1046 10 <tab>2 <tab>6 <tab>xmzdtttgus <tab>528 <tab>65525 4. RAWinFILE = 3016 3 <tab>9 <tab>10 <tab>hvvzem <tab>423 <tab>65518 5. RAWinFILE = 1497 1 <tab>8 <tab>8 <tab>quifcdp <tab>144 <tab>65515 1. PROCESSED = item 3635 data 2 <tab>1 <tab>4 <tab>pguyda <tab>915 <tab>65534 2. PROCESSED = item 2828 data 9 <tab>3 <tab>8 <tab>cnitrkds <tab>557 <tab>65529 3. PROCESSED = item 2036 data 10 <tab>2 <tab>6 <tab>xmzdtttgus <tab>528 <tab>65525 4. PROCESSED = item 1130 data 3 <tab>9 <tab>10 <tab>hvvzem <tab>423 <tab>65518 5. PROCESSED = item 2022 data 1 <tab>8 <tab>8 <tab>quifcdp <tab>144 <tab>65515 The methodology (i think thats the right word for it), is that when u hsave a hashtable, it is saved in the same order as you can access it using the $hget(table,N).item & .data properties (i would assume this is physical order in memory). So you hsave just the data, but when u filter sort it, u add the -n option that adds line numbers to the output file (line number of the line from the input file), this gives u the N value to backrefrence into the table using $hget(table,N).item * Considering also what the OP has stated about the hashtable being loaded from a file in the first place, the key might infact be to filter sort the file before its even loaded into the table, thus giving the actual itemnames 1,2,3,4,5 the 5 in order he wants. Im still a bit unclear on what hes doing with that tho. sicne the sort might be something he wants done afterwards at some later time. ** On a personal note, glad to see you back KT, You were here in a major way when i first started using mirc to script stuff, and I respected your input on anything i was doing, yours and a few others i wont name here tho incase i miss someone in the list, although the initials FO come bounding out of the page as someone who also deserves credit for his help.
|
|
|
|
Joined: Apr 2006
Posts: 464
Fjord artisan
|
OP
Fjord artisan
Joined: Apr 2006
Posts: 464 |
Alright, to give a bit of feedback. I play this game, with loads of planets. MikeChat helped me downloading their database dumps in this threadSo, the idea of the script is to read that txt file using my bot. Like !whois x:y:z will give you information on size, score etc. Almost like an interface to the game itself When searching ($read) for info from this txt file, using wildmatch (iswm) characters, and processing all 3200+ lines, I noticed it freezes my bot for like 10 to 12 seconds. And that was for only 1 request, imagine 5 people use the same command!!!! Obviously not the way forward. So I started using hash tables instead and load the txt file in a hash table every hour. Now I want to make all kinds of scripts that can read from this hash table. Like for example the top5 requested above. I have to say the script of KingTomato works like a charm. I'm fine tuning that, and it's now returning the info in like 2/3 seconds. Obviously already a lot better. Thx to ya'll for the help guys
|
|
|
|
Joined: Sep 2003
Posts: 4,230
Hoopy frood
|
Hoopy frood
Joined: Sep 2003
Posts: 4,230 |
10 to 12 seconds to read a text file with 3200 lines using wildmatch? omg where did u save the file to floppydisk? I loaded KingTomatoe's and ran it, and his was taking around 1.05 seconds to function on mine now here is the problem with that the 1.00 was to get the hashtable data into the window the 0.05 was to sort it and output it in the order wanted see the problem using /hsave -n table file | /filter -ff file file method, takes around 0.10 seconds to hsave and 0.06 seconds to display results 0.16 is significantly better than 1.05. assuming your getting 2 to 3 second results, i would assume that translats to 0.36/0.48 second results using /hsave
I well look at this other thread u mentioned and maybe come back with example code of how to source from the file itself.
* either way, I think a better solution for you might be to load the file to a hidden window, rather than a hashtable, a hashtables advanatage is for quick access to each bit of data based on supplying its unquie ITEMNAME, from what i understand your keeping all the info in the data, and thus this makes the use of a hashtable unlikely to be the correct tool.
|
|
|
|
Joined: Sep 2003
Posts: 4,230
Hoopy frood
|
Hoopy frood
Joined: Sep 2003
Posts: 4,230 |
;
;usage /updateinfo
;
alias updateinfo {
sockclose gameinfo
sockopen gameinfo game.planetarion.com 80
}
on *:sockopen:gameinfo:{
///echo -st sockopen : $sockname
sockwrite -n $sockname GET http://game.planetarion.com/botfiles/planet_listing.txt HTTP/1.1
sockwrite $sockname HOST: game.planetarion.com $+ $crlf $+ $crlf
.remove GAMEINFO.NEW
}
on *:sockread:gameinfo:{
if ($sockerr > 0) return
if ($sock(gameinfo).mark != 2) {
var %txtvar
sockread -n %txtvar
///echo -st sockread : TXT : $sock(gameinfo).mark : $len(%txtvar) : %txtvar
if (!$len(%txtvar)) {
sockmark gameinfo $calc($sock(gameinfo).mark + 1)
}
}
else {
sockread &binvar
///echo -st sockread : BIN : $sock(gameinfo).mark : $bvar(&binvar,0)
bwrite GAMEINFO.NEW -1 -1 &binvar
}
}
on *:sockclose:gameinfo:{
///echo -st sockclose : $isfile(GAMEINFO.NEW)
if ($isfile(GAMEINFO.NEW)) {
.remove GAMEINFO.TXT
.rename GAMEINFO.NEW GAMEINFO.TXT
hfree -w GAMEINFO
hmake GAMEINFO 1000
hload -n GAMEINFO GAMEINFO.TXT
}
}
;
;usage /sort.gameinfo N [A|D]
; or
;usage $sort.gameinfo(N,[A|D])
;
; N = column to sort on
; A = Assending sort
; D = Descending sort (default if not entered)
;
;returns $true if completed, $false if failed.
;
alias sort.gameinfo {
if (($int($1) isnum 1-10) && (($2 == $null) || ($2 == A) || ($2 == D))) {
hsave -n GAMEINFO GAMEINFO.TXT
filter $+(-ffcu,$iif(($2 == A),e),t) $int($1) 9 GAMEINFO.TXT GAMEINFO.TXT
hfree -w GAMEINFO
hmake GAMEINFO 1000
hload -n GAMEINFO GAMEINFO.TXT
return $true
}
else { return $false }
}
;
; To access the sorted order of the hashtable use $hget(GAMEINFO,N)
; N = value of order position required,;
;
; example1: top five scores (column 8)
; //sort.gameinfo 8 D
; //echo -a 1st $hget(GAMEINFO,1)
; //echo -a 2st $hget(GAMEINFO,2)
; //echo -a 3st $hget(GAMEINFO,3)
; //echo -a 4st $hget(GAMEINFO,4)
; //echo -a 5st $hget(GAMEINFO,5)
;
; example2: top five size (column 7)
; //sort.gameinfo 7 D
; //echo -a 1st $hget(GAMEINFO,1)
; //echo -a 2st $hget(GAMEINFO,2)
; //echo -a 3st $hget(GAMEINFO,3)
; //echo -a 4st $hget(GAMEINFO,4)
; //echo -a 5st $hget(GAMEINFO,5)
; ok i updated the pull down code a little, normally u want to just dump the file header (ends at the first $null string), but i noticed the actual data u want has some lines before it, followed by a $null string (empty line), so i dump everything before the 2nd $null, I then switch to binary read, just becuase i do my sockreads like that to file. The echos with 3 /// at the front are just so u can observe it in action, remark or remove them when you feel like it. I make a file called GAMEINFO.NEW, and only once its completed do i replace the GAMEINFO.TXT file, this is becuase anything might happen during the downloading process (website fails etc) ok and once its downloaded, it replaces the old GAMEINFO hashtable I assumed NO OTHER DATA exists in the table. If it does i would suggest you use a second tablename to hold it. now since there is no itemnames just data i used the /hload -n option to load the data meaning the table is revrenced using itemnames 1,2,3.... but its just in the order it came from the website. Now if u want sorted order simply used $sort.gameinfo(Column,[A|D]) A=accending D=deccending (default if u dont put it in) what this does is actually dumps the hashtable to file, sorts it as needed and reloads it into the hashtable, the data thus gets issued itemnames 1,2,3.... in the order you speciifed * On tables the size yours are this is a functional and fast option, dont be doing it on tables 20meg in size in other words (well actually i do but hey i got bulk ram)
|
|
|
|
Joined: Apr 2006
Posts: 464
Fjord artisan
|
OP
Fjord artisan
Joined: Apr 2006
Posts: 464 |
That looks pretty amazing DaveC. I'm gonna test a little with it tonight, and see how the code works in practise. This code at the moment is way over my head, but by testing and trying I should be able to understand how it all works.
In any case a big thx for your effort, looks really slick.
|
|
|
|
Joined: Feb 2004
Posts: 2,019
Hoopy frood
|
Hoopy frood
Joined: Feb 2004
Posts: 2,019 |
On a personal note, glad to see you back KT, You were here in a major way when i first started using mirc to script stuff, and I respected your input on anything i was doing, yours and a few others i wont name here tho incase i miss someone in the list, although the initials FO come bounding out of the page as someone who also deserves credit for his help. o.O that's nice to hear! And I think you are one of the best helpers around here for the last year, and one of the best scripters around here as well.
Gone.
|
|
|
|
|