HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

TimerUtils (Purple)

02-17-2009, 10:46 AM#1
Iron_Doors
A third flavor to accompany Vexorian's Blue and Red TimerUtils.

Table:
Purple TimerUtils
- Uses the attaching method used in an early version of Cohadar's ABCT (which is a tiny bit different from what he uses now)
- array lookup, multiplication, division, subtraction, H2I (Get/SetTimerData get inlined)
- There is a theoretical condition for this to work in your map, which is that you can have no more than 4096 timers simultaneously, and in practice I'd assume no more than 3000.

In short, this thing is faster than the Blue flavor but still safe enough for most. A speed freak with a carefully handled Red TimerUtils might not be interested, but for the rest I believe this is a good choice.

EDIT: After 1.23b the Blue flavor became much faster than it was before, so the above might not hold true anymore.

Collapse Purple TimerUtils (patch 1.23b or later):
library_once TimerUtils
//*********************************************************************
//* TimerUtils (Purple flavor for 1.23b or later)
//* ----------
//*
//*  To implement it , create a custom text trigger called TimerUtils
//* and paste the contents of this script there.
//*
//*  To copy from a map to another, copy the trigger holding this
//* library to your map.
//*
//* (requires vJass)   More scripts: http://www.wc3c.net/
//*
//* For your timer needs:
//*  * Attaching
//*  * Recycling (with double-free protection)
//*
//* set t=NewTimer()      : Get a timer (alternative to CreateTimer)
//* ReleaseTimer(t)       : Relese a timer (alt to DestroyTimer)
//* SetTimerData(t,2)     : Attach value 2 to timer
//* GetTimerData(t)       : Get the timer's value.
//*                         You can assume a timer's value is 0
//*                         after NewTimer.
//*
//* Purple Flavor: Slower than the red flavor by a multiplication and a
//*             division, and as such faster than the blue flavor. Has
//*             a theoretical limit of timers, which is HASH_SIZE, but
//*             you should keep your timer count below 3/4 of that to
//*             insure good performance of the NewTimer function.
//*
//* Credits:  * Hash algorithm by Cohadar (used in an early version
//*             of his ABCT timer system)
//*
//*           * TimerUtils "interface" by Vexorian.
//*
//*           * This library by Iron_Doors.
//*
//********************************************************************

//================================================================
    globals // These are the hash constants Cohadar used in an early version of ABCT
        private constant integer HASH_SIZE = 4096       // 2^12
        private constant integer HASH_UP   = 2138046464 // 2^(31-(12-1)) * 2039
        private constant integer HASH_DOWN = 1048576    // 2^(31-(12-1))
        private constant integer HASH_BIAS = 2048       // 2^(12-1)
    endglobals

    //==================================================================================================
    globals
        private integer array Data[HASH_SIZE]
        private timer array Timer[HASH_SIZE]
    endglobals
    
    function SetTimerData takes timer t, integer value returns nothing
        debug if (Timer[GetHandleId(t) * HASH_UP / HASH_DOWN + HASH_BIAS] != t) then
        debug     call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
        debug endif
        set Data[GetHandleId(t) * HASH_UP / HASH_DOWN + HASH_BIAS] = value
    endfunction

    function GetTimerData takes timer t returns integer
        debug if (Timer[GetHandleId(t) * HASH_UP / HASH_DOWN + HASH_BIAS] != t) then
        debug     call BJDebugMsg("GetTimerData: Wrong handle id, only use GetTimerData on timers created by NewTimer")
        debug endif
        return Data[GetHandleId(t) * HASH_UP / HASH_DOWN + HASH_BIAS]
    endfunction

    //==========================================================================================
    globals
        private integer array tH
        private integer tN = 0
        private constant integer HELD=0x28829022
        //use a totally random number here, the more improbable someone uses it, the better.
    endglobals

    //==========================================================================================
    function NewTimer takes nothing returns timer
     local timer t
        if (tN == 0) then
            loop
                set t = CreateTimer()
                set tH[0] = GetHandleId(t) * HASH_UP / HASH_DOWN + HASH_BIAS
                exitwhen Timer[tH[0]] == null
            endloop
            set Timer[tH[0]] = t
        else
            set tN = tN - 1
        endif
        set Data[tH[tN]] = 0
     return Timer[tH[tN]]
    endfunction

    //==========================================================================================
    function ReleaseTimer takes timer t returns nothing
        if (t == null) then
            debug call BJDebugMsg("Warning: attempt to release a null timer")
            return
        endif
        debug if (Timer[GetHandleId(t) * HASH_UP / HASH_DOWN + HASH_BIAS] != t) then
        debug     call BJDebugMsg("ReleaseTimer: Wrong handle id, only use ReleaseTimer on timers created by NewTimer")
        debug endif
        call PauseTimer(t)
        set tH[tN] = GetHandleId(t) * HASH_UP / HASH_DOWN + HASH_BIAS
        if (Data[tH[tN]] == HELD) then
            debug call BJDebugMsg("Warning: ReleaseTimer: Double free!")
            return
        endif
        set Data[tH[tN]] = HELD
        set tN = tN + 1
    endfunction

endlibrary
02-17-2009, 12:46 PM#2
Vexorian
- Pick another color, green is reserved for a different implementation.
- This is faster than blue when using certain definitions of faster.
02-17-2009, 01:09 PM#3
Iron_Doors
Quote:
Originally Posted by Vexorian
- Pick another color, green is reserved for a different implementation.
As you wish :)

Quote:
Originally Posted by Vexorian
- This is faster than blue when using certain definitions of faster.
I don't get what you're trying to say here to be honest, but I hope its nothing bad.
02-17-2009, 01:57 PM#4
darkwulfv
So... like, how big of a difference are we talking here? Just saying its faster means nothing until you show it with benchmarks.
02-17-2009, 02:07 PM#5
Rising_Dusk
You know, just posting TimerUtils with a different implementation of its storage doesn't merit approval or anything. Post it in the TimerUtils thread.
02-17-2009, 02:09 PM#6
Vexorian
I am not sure if it would be better to post it in TimerUtils, maybe it is better this way.
02-17-2009, 02:11 PM#7
Rising_Dusk
Well you're the boss. I think this is quite silly, though.
02-17-2009, 02:41 PM#8
Captain Griffen
Benchmarks or I graveyard. Particularly against red, since this is almost no safer than red. You'll die to a timer leak, exactly the same conditions under which red will die if properly setup.
02-17-2009, 02:47 PM#9
darkwulfv
Well he did say it was slower than red but faster than blue. I really think it's just another example of "pick which of the 50 timer storages suits you best".
02-17-2009, 02:49 PM#10
Flame_Phoenix
Quote:
"pick which of the 50 timer storages suits you best".
Amen
02-17-2009, 04:27 PM#11
Captain Griffen
Quote:
Originally Posted by darkwulfv
Well he did say it was slower than red but faster than blue. I really think it's just another example of "pick which of the 50 timer storages suits you best".

Slower and not really any more safe implies GY.
02-17-2009, 05:15 PM#12
Rising_Dusk
I'm with Griffen on this one. I don't think having infinitely many storage systems merits anything other than Blue or Red. Those two cover everything we could possibly need fine and dandy. Unless this method is faster than Blue, it really isn't valid. Red works totally differently, which is why it's a different flavour in the first place.
02-17-2009, 06:35 PM#13
Flame_Phoenix
Quote:
Originally Posted by Rising_Dusk
Unless this method is faster than Blue, it really isn't valid.
Quote:
Originally Posted by Iron_Doors
In short, this thing is faster than the Blue flavor but still safe enough for most.
Quote:
Originally Posted by Vexorian
- This is faster than blue when using certain definitions of faster.
Quote:
Originally Posted by Griffen
Benchmarks or I graveyard.

So, before we all make more posts about this matter, to resume what we should do/need: benchmarks
02-17-2009, 06:59 PM#14
Rising_Dusk
We all know it needs benchmarks, dude, but we're still free to voice our stance on the matter pending such benchmarks.
02-17-2009, 07:14 PM#15
Flame_Phoenix
Quote:
We all know it needs benchmarks, dude, but we're still free to voice our stance on the matter pending such benchmarks.
True, but there isn't much to talk about without benchmarks, I mean, most of it will be speculation (which is bad imho).