mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Nov 2004
Posts: 148
D
Vogon poet
OP Offline
Vogon poet
D
Joined: Nov 2004
Posts: 148
Would you mind adding an option to the /hadd -uN so you will be able to add command to be executed when the item expired?

Doing the same thing with timers is complicated and takes lots of resources when the hash table has lots of items (1000, or even 10,000), not to mention that the loop should be executed every second in order to check if an item has expired or needs to be expired (in case a time is the one which expires it).

Thanks.

Joined: Oct 2003
Posts: 96
J
Babel fish
Offline
Babel fish
J
Joined: Oct 2003
Posts: 96
Yeah that would be nice .. or maybe even an event ..

hash tables
on *:HEXPIRE:table:item:command
with option to use wildcards for table and item.
fill $1- with the data of the expired item.
fill $table & $item too.

variables
on *:VEXPIRE:name:command
with option to use wildcards for name.
fill $1- with the data of the expired variable.
fill $name or $variable too.

this would be great smile

Last edited by JoeDaddy; 23/12/04 04:11 PM.
Joined: Jan 2003
Posts: 56
E
Babel fish
Offline
Babel fish
E
Joined: Jan 2003
Posts: 56
Code:
alias hadd {
  if (-*u* iswm $1) && (($hget($2) != $null) || (-*m* iswm $1)) && ($3 != $null) {
    var %t = $+(.timer,_hexp,$ticks)
    %t -hi 0 500 _hexp $2 $3 %t
    hadd -m hexpire $+($2,$3) $4-
  }
  hadd $1-
}
alias -l _hexp {
  if ($hget($1,$2) != $null) return
  $3 off
  hadd hexpire table $1
  hadd hexpire item $2
  .signal -n hexpire $hget(hexpire,$+($1,$2))
}
alias table return $hget(hexpire,table)
alias item return $hget(hexpire,item)

; Example code to test it

on *:signal:hexpire: {
  echo -a table: $table
  echo -a item: $item
  echo -a value: $1-
}  

Joined: Sep 2003
Posts: 4,230
D
Hoopy frood
Offline
Hoopy frood
D
Joined: Sep 2003
Posts: 4,230
Nice bit of code but it runs into the large number of timers problem. Ever tried launching 10,000 timers?

Joined: Nov 2004
Posts: 148
D
Vogon poet
OP Offline
Vogon poet
D
Joined: Nov 2004
Posts: 148
I did grin

I made something like:
/timer 0 0 timer 0 0 timer 0 0 timer 0 0 timer 0 0 timer 0 0 timer 0 0 timer 0 0 timer 0 0 timer 0 0 timer 0 0 timer 0 0 timer 0 0 timer 0 0 timer 0 0 timer 0 0 echo hello


Just to see how much time it takes to kill windows grin

Joined: Jan 2003
Posts: 56
E
Babel fish
Offline
Babel fish
E
Joined: Jan 2003
Posts: 56
For what do you need 10.000 items? If you do not need to run a command for all of these i could just add a /hadd -r to run a signal and else not.

Joined: Nov 2004
Posts: 148
D
Vogon poet
OP Offline
Vogon poet
D
Joined: Nov 2004
Posts: 148
I'm not familiar with the -r switch. What does it do?

Joined: Jan 2003
Posts: 56
E
Babel fish
Offline
Babel fish
E
Joined: Jan 2003
Posts: 56
Code:
alias hadd {
  if (-*u* iswm $1) && (($hget($2) != $null) || (-*m* iswm $1)) && ($3 != $null) && (-*r* iswm $1) {
    var %t = $+(.timer,_hexp,$ticks)
    %t -hi 0 500 _hexp $2 $3 %t
    hadd -m hexpire $+($2,$3) $4-
  }
  hadd $1-
}
alias -l _hexp {
  if ($hget($1,$2) != $null) return
  $3 off
  hadd hexpire table $1
  hadd hexpire item $2
  .signal -n hexpire $hget(hexpire,$+($1,$2))
}
alias table return $hget(hexpire,table)
alias item return $hget(hexpire,item)

; Example code to test it

on *:signal:hexpire: {
  echo -a table: $table
  echo -a item: $item
  echo -a value: $1-
} 


This will just start a timer (resulting in a signal after unset) if you use hadd -ru60 f.e.

Joined: Sep 2003
Posts: 4,230
D
Hoopy frood
Offline
Hoopy frood
D
Joined: Sep 2003
Posts: 4,230
Quote:
For what do you need 10.000 items?


The original message specified 1000 to 10000

Quote:
Doing the same thing with timers is complicated and takes lots of resources when the hash table has lots of items (1000, or even 10,000),


Your code also breaks down if two items are both /hadd'ed one after the other, since the timername is identicel for both, I didnt mention this earlier, as i didnt think the multiple timer idea held much water (I also suggested it in scripts&popups i think) but as said here, the large number of timers is a cpu/resource hog

I must admit this one caught my eye, as soemthing to play around with, an internal command to trigger and event or store a command to run would be real nice, but what can one do in the interim. I have tried 2 things out so far, neither held sucsess when tried with large tables.

Joined: Nov 2004
Posts: 148
D
Vogon poet
OP Offline
Vogon poet
D
Joined: Nov 2004
Posts: 148
I have to ideas in mind on a possible way of doing something similar:

1) The data will be stored in 2 hash tables. One of them will have the items expired after a period and the other the items doesn't expired.
Every second it checks the number of items in each of the tables. If the number doesn't match then it finds out which lines are missing (I think that it will require a loop cause /filter doesn't have this kind of option as /filter -xww window1 window2 window3, where the content od window3 will be the lines which are different. Also /filter doesn't work with hash table, but I remember that it was suggested few months ago by saragini). After it execute the command, it will remove the data from the second hash table.

2) the second idea requires only hash table, and its data doesn't expire, but it contains the information about when it needs to be expired. A timer is execute a command every second in order to check if an item need to be expired and then it also execute a command.
A nicer idea is to have the function check when the next item needs to be exired and set the original timer to have a delay that match the expire delay (in order to have a variable delay other than checking the table every second).

Still, it would be nicer having /hadd with an execute option. smile

Joined: Sep 2003
Posts: 4,230
D
Hoopy frood
Offline
Hoopy frood
D
Joined: Sep 2003
Posts: 4,230
Quote:
1) The data will be stored in 2 hash tables. One of them will have the items expired after a period and the other the items doesn't expired.


OMG i was working on the assumption you were trying to tap into someone elses script/hashtable and trigger events when things unset. So its your own code, so you could easily create a special command such as /haddcommand delimiter args table name value delimiter command
thus the alias can use $1 look for it in $5- and know $5 to the delimiter is the value and after the delimiter is the command. That would make all that insane signal stuff unneeded.

Ill rewrite what i have I think on that basis.

Quote:
Every second it checks the number of items in each of the tables. If the number doesn't match then it finds out which lines are missing (I think that it will require a loop cause /filter doesn't have this kind of option as /filter -xww window1 window2 window3, where the content od window3 will be the lines which are different. Also /filter doesn't work with hash table, but I remember that it was suggested few months ago by saragini). After it execute the command, it will remove the data from the second hash table.


Well bizzarely i just asked a question on how to get the differences between 2 windows the other day, the code is very short, it does uses a loop, but an internal one, by filtering windows 1 to an alias using -k, the alias then sees if the passed value is in window2 and if not writes it to window3, u can get the hash tables into the windows by using LOADBUF although filter works with files, i dont think its as fast, i havent tested that tho.

Quote:
2) the second idea requires only hash table, and its data doesn't expire, but it contains the information about when it needs to be expired. A timer is execute a command every second in order to check if an item need to be expired and then it also execute a command.


My idea is a cross of the two, allow the normal table to exist, and keep a second table (but not hash) of the unsetting ones, which stores data about the unset time etc.

Quote:
A nicer idea is to have the function check when the next item needs to be exired and set the original timer to have a delay that match the expire delay (in order to have a variable delay other than checking the table every second).


well assuming your initial check doesnt have to do much (no looping) then once a second wont be a worry, i have things going off once a second for all types of things, you never even know there happening.

Quote:
Still, it would be nicer having /hadd with an execute option. smile

I hope it is added, it sounds like a excellent idea, im not sure how the command should be passed & stored of course, maybe in a hashtable of commands, with the orginaltablename~itemname as its item name and it as data, but then maybe thats looking at it from a end user point, and Khaled has a much better understanding of the way things would/should be.

Ill post what i have in a few minutes im just bug testing it. Its doing 10,000 unset catches with out lagging in the monitoring of them, of course if all 10,000 unset at once its gonna put some lag on dealing with 10,000 commands LOL

Joined: Sep 2003
Posts: 4,230
D
Hoopy frood
Offline
Hoopy frood
D
Joined: Sep 2003
Posts: 4,230
i just finished testing mine, had a big delay when i discovered hashtable names and items can have * and ? in them, and had to build a regex which im crap at. Try this out, its docuemnted so shouldnt be to hard to understand.
Code:
;
; *****************************************************************
; *  Script to add commands to run when a hashtable item unsets.  *
; *****************************************************************
;
; Altered commands   /hadd -r N table item value $chr(N) command
;
;   In the altered -r command N represents the asc value of the delimiter character between "value" and "command" (ie token seperator)
;
;   The altered command must be incorperated into a standard /hadd command that well produce an unsetting item, example... 
;     /hadd -ru100 44 myTable myItem myValue , echo -s Hashtable myTable Item myItem set at $time just unset at $!time
;
;   If the /hadd command does not create a item that has an $hget(table,item).unset value the command well be ignored.
;
;
;
; Added commands     /hcmd -Ww[s|c|d] N table item command  : Used to show, change or delete commands.
;                    $hcmd(-Ww[s|c|d],N,table,item,command) : Used to show, change or delete commands.
;   Exact Match Usage...
;     Show             /hcmd -s table item
;     Change           /hcmd -c table item command
;     Delete           /hcmd -d table item
;
;   Wildmatch Usage...
;     Show Wildmatch Table         /hcmd -sW N table item
;     Show Wildmatch Item          /hcmd -sw N table item
;     Show Wildmatch Table & Item  /hcmd -sWw N table item
;       In wildcard matches N represents the Nth match, N = 0 returns the total number of matches.
; 
;   The following values are returned from this identifier
;     $1  =  hashtable name
;     $2  =  hashtable item
;     $3- =  command
;
;   Switches -s -c -d are mutually exclusive commands, in the event two or more are present -s superseeds -c which superseeds -d.
;
;
;
; Added events       on *:signal:hashtable.on.unset.command.stack:{ } A example event is at the bottom of this file.
;
;   This event triggers when a hashtable item is detected to have been unset, this normally is within .5 seconds but may be longer.
;
;   The following values are passed to this event
;     $1  =  Estermated tick count at unset time this well be lower than the current $tick but well not always match near the time of the unset
;     $2  =  Internal counter of number of incorrect estermations of the $1 value that were updated (if zero unset most likely within .5 seconds)
;     $3  =  cid of the script that produced (/hadd -r) or last updated (/hcmd -c) the command
;     $4  =  hashtable name
;     $5  =  item name
;     $6- =  command
;
;
;
; Monitored Commands  
;   /hfree well remove all unset event commands for table when table is destroyed
;   /hinc  well remove any unset event command for table item if item no longer has an $hget(table,item).unset value
;   /hdec  well remove any unset event command for table item if item no longer has an $hget(table,item).unset value
;   /hdel  well remove any unset event command for table item when table item is detroyed
;
alias hcmd {
  if (-* !iswm $1) {
    var %number = 1
    var %table.name = $Make.Regex.Ready($1)
    var %table.item = $Make.Regex.Ready($2)
    var %command = $3-
  }
  else {
    if (-*w* iswm $1) {
      var %number = $2
      var %table.name = $Make.Regex.Ready($3)
      var %table.item = $Make.Regex.Ready($4)
      var %command = $5-
      if (-*W* iswmcs $1) {
        %table.name =  $replace(%table.name,\*,.*,\?,.)
      }
      if (-*w* iswmcs $1) {
        %table.item =  $replace(%table.item,\*,.*,\?,.)
      }
    }
    else  {
      var %number = 1
      var %table.name = $Make.Regex.Ready($2)
      var %table.item = $Make.Regex.Ready($3)
      var %command = $4-
    }
  }
  if (-*s* iswm $1) || (-* !iswm $1) || ((-*c* !iswm $1) && (-*d* !iswm $1)) {
    var %line = $fline($hashtable.on.unset.command.stack,/^\d+\x9\d+\x9\d+\x9 $+ %table.name $+ \x9 $+ %table.item $+ \x9.*$/,%number,2)
    if (%line) && (%number != 0) {
      %line = $line($hashtable.on.unset.command.stack,%line)
      %line = $gettok(%line,4,9) $gettok(%line,5,9) $gettok(%line,6-,9)
    }
    if ($isid = $false) && (%line != $null) {
      echo -se /hcmd: $1-
      echo -se /hcmd: %line
    }
    return %line
  }
  elseif (-*c* iswm $1) && (%number != 0) {
    var %line = $fline($hashtable.on.unset.command.stack,/^\d+\x9\d+\x9\d+\x9 $+ %table.name $+ \x9 $+ %table.item $+ \x9.*$/,%number,2)
    rline $hashtable.on.unset.command.stack %line $puttok($gettok($line($hashtable.on.unset.command.stack,%line),1-5,9),$cid,3,9) $+ $chr(9) $+ %command
  }
  elseif (-*d* iswm $1) && (%number != 0) {
    var %line = $fline($hashtable.on.unset.command.stack,/^\d+\x9\d+\x9\d+\x9 $+ %table.name $+ \x9 $+ %table.item $+ \x9.*$/,%number,2)
    dline $hashtable.on.unset.command.stack %line
  }
}
;hmake * no alias needed
alias hfree {
  hfree $1-
  if (-* iswm $1) {
    var %table.name = $Make.Regex.Ready($2)
    if (-*w* iswm $1) {
      %table.name =  $replace(%table.name,\*,.*,\?,.)
    }
  }
  else {
    var %table.name = $Make.Regex.Ready($1)
  }
  filter -cxgww $hashtable.on.unset.command.stack $hashtable.on.unset.command.stack  /^\d+\x9\d+\x9\d+\x9 $+ %table.name $+ \x9.*$/
}
alias hadd {
  if (-*r* !iswm $1) {
    hadd $1-
  }
  else {
    if ($2 !isnum 1-255) {
      echo -se /hadd: /hadd -r option requires the following format /hadd -r N table item value $!chr(N) command.
      echo -se /hadd: N must be from 1 to 255 and selects the delimiter character that must appear between the hashtable value and unset event command.
      echo -se /hadd: It is preferable that the delimiter does not appear anywhere else on the line.
      halt
    }
    else {
      var %command = $gettok($5-,2-,$2)
      tokenize 32 $1 $3 $4 $gettok($5-,1,$2)
      hadd $1-
      hadd.hashtable.on.unset.command.stack $1 $2 $3 %command
    }
  }
}
alias hinc {
  hinc $1-
  if (-* iswm $1) tokenize 32 $2-
  update.hashtable.on.unset.command.stack $1-
}
alias hdec {
  hdec $1-
  if (-* iswm $1) tokenize 32 $2-
  update.hashtable.on.unset.command.stack $1-
}
alias hdel {
  hdel $1-
  hdel.hashtable.on.unset.command.stack $1-
}
alias -l update.hashtable.on.unset.command.stack {
  var %table.name = $Make.Regex.Ready($1)
  var %table.item = $Make.Regex.Ready($2)
  var %line.number = $fline($hashtable.on.unset.command.stack,/^\d+\x9\d+\x9\d+\x9 $+ %table.name $+ \x9 $+ %table.item $+ \x9.*$/,1,2)
  if (%line.number) {
    var %line = $line($hashtable.on.unset.command.stack,%line.number)
    hadd.hashtable.on.unset.command.stack -r $1 $2 $gettok(%line,6-,9)
  }
}
alias -l hadd.hashtable.on.unset.command.stack {
  hdel.hashtable.on.unset.command.stack $2 $3
  if (-*r* iswm $1) && ($hget($2,$3).item != 0) && ($hget($2,$3).unset > 0) {
    aline $hashtable.on.unset.command.stack [ $calc($ticks + $ifmatch * 1000) ] $+ $chr(9) $+ 0 $+ $chr(9) $+ $cid $+ $chr(9) $+ $2 $+ $chr(9) $+ $3 $+ $chr(9) $+ $4-
  }
}
alias -l hdel.hashtable.on.unset.command.stack {
  if (-* iswm $1) {
    var %table.name = $Make.Regex.Ready($2)
    var %table.item = $Make.Regex.Ready($3)
    if (-*w* iswm $1) {
      %table.item =  $replace(%table.item,\*,.*,\?,.)
    }
  }
  else {
    var %table.name = $Make.Regex.Ready($1)
    var %table.item = $Make.Regex.Ready($2)
  }
  filter -cxgww $hashtable.on.unset.command.stack $hashtable.on.unset.command.stack  /^\d+\x9\d+\x9\d+\x9 $+ %table.name $+ \x9 $+ %table.item $+ \x9.*$/
}
alias -l Make.Regex.Ready {
  var %text = $replace($1-,   \,\\,   $chr(32),\s,   $,\$,   $chr(40),\ $+ $chr(40),   $chr(41),\ $+ $chr(41),   *,\*,   +,\+,   .,\.,   ?,\?,   [,\[,   ],\],   ^,\^,   $chr(123),\ $+ $chr(123),   |,\|,   $chr(125),\ $+ $chr(125))
  var %text = $replace(%text, \s,$chr(32),   a,(a|A),b,(b|B),c,(c|C),d,(d|D),e,(e|E),f,(f|F),g,(g|G),h,(h|H),i,(i|I),j,(j|J),k,(k|K),l,(l|L),m,(m|M),n,(n|N),o,(o|O),p,(p|P),q,(q|Q),r,(r|R),s,(s|S),t,(t|T),u,(u|U),v,(v|V),w,(w|W),x,(x|X),y,(y|Y),z,(z|Z),   $chr(32),\s)
  return ( $+ %text $+ )
}
alias hashtable.on.unset.command.stack {
  if (!$window(@hashtable.on.unset.command.stack)) window -hns -t10,20,30,40,50,60,70 @hashtable.on.unset.command.stack
  if (!$timer(.hashtable.on.unset.command.stack.despooler)) .timer.hashtable.on.unset.command.stack.despooler -o 0 1 if (!$line($hashtable.on.unset.command.stack,0)) || ($line($hashtable.on.unset.command.stack,1) <= $!ticks) hashtable.on.unset.command.stack.despooler
  window -hn @hashtable.on.unset.command.stack
  return @hashtable.on.unset.command.stack
}
alias -l hashtable.on.unset.command.stack.despooler {
  if ($line($hashtable.on.unset.command.stack,1) <= $ticks) {
    var %line = $ifmatch
    var %table.name = $gettok(%line,4,9)
    var %table.item = $gettok(%line,5,9)
    if ($hget(%table.name,%table.item).unset) {
      var %respool.count = $gettok(%line,2,9)
      inc %respool.count 
      aline $hashtable.on.unset.command.stack [ $calc($ticks + $ifmatch * 1000 * %respool.count) ] $+ $chr(9) $+ %respool.count $+ $chr(9) $+ $gettok(%line,3-,9)
      dline $hashtable.on.unset.command.stack 1
    }
    else {
      .signal -n hashtable.on.unset.command.stack $gettok(%line,1,9) $gettok(%line,2,9) $gettok(%line,3,9) %table.name %table.item $gettok(%line,6-,9)
      dline $hashtable.on.unset.command.stack 1
    }
  }
  if ($line($hashtable.on.unset.command.stack,0)) {
    .timer 1 0 if ($line($hashtable.on.unset.command.stack,1) <= $!ticks) hashtable.on.unset.command.stack.despooler
  }
  else {
    close -@ $hashtable.on.unset.command.stack
    .timer.hashtable.on.unset.command.stack.despooler off
  }
}
;
; Example event below
;
on *:signal:hashtable.on.unset.command.stack: {
  echo -st Hashtable Unset event occured values passed : $1-
  ;Following commands well run the command passed
  ;
  ; scid $3
  ; [ [ $6- ] ]
} 


Damn thats a big post <grin> Sorry should have emailed it to you.

Last edited by DaveC; 28/12/04 11:14 PM.
Joined: Nov 2004
Posts: 148
D
Vogon poet
OP Offline
Vogon poet
D
Joined: Nov 2004
Posts: 148
Thanks, I'l look into your code.


Link Copied to Clipboard