• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[General] [feedback] hashtable replacement

Status
Not open for further replies.

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,219
hello. I just came across an idea concerning hashtables.

Generally you use a unit's handle id as one key and then a number as the other key.

Then I thought of the following, if I could replace the 2d array with an 1d array that would be really good.
  • Melee Initialization
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Hashtable - Create a hashtable
      • Set my_hashtable = (Last created hashtable)
      • -------- ----------------- --------
      • Set some_real = 55.00
      • Set some_unit = Mountain King 0000 <gen>
      • -------- ----------------- --------
      • Hashtable - Save some_real as (Key (Triggering unit)) of 1 in my_hashtable
      • Hashtable - Save Handle Ofsome_unit as (Key (Triggering unit)) of 2 in my_hashtable
  • Actions
    • Custom script: set udg_id = GetHandleId(somehandle)
    • Set random_integer[id] = 77
    • Set random_real[id] = 5656.00
wouldnt this have the exact same effect but faster. I guess the limit of handles would be much much much lower tho.
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
It's possible, the old guys used it back then, I think the value was 0x100000 (? not sure). You offset the handle id with that value (handleid-offset) to get a valid (0-8191) array index. It has a problem though, if the handle id's don't get recycled then the system will fail after using a value that exceeds 8191.
 
A unit indexer is much better. As chobibo said, you can subtract a particular offset to get it to a proper range 0-8191, but there are many cases where the handle ID's might exceed 0x101FFF (or 1056767), where you'll get an index above 8191. Handle ID's (or more accurately, agent ID's) begin at 0x100000, which equals 1048576. You can also make a flexible offset to fix some of that, but in general it isn't perfectly reliable with something as dynamic as units (they come and leave the game so often), especially in big maps. There are a few GUI functions that leak handle indexes, so running into the index problem is very possible. (P.S. if you divide by a million, then you'll end up with overlaps where units get the same ID's, and you'll run into issues)

A unit indexer circumvents this by assigning each unit on the map a custom user data (or at least, the ones that should be indexed), ranging from 0-8191. When a unit is removed, it is deindexed so that other units can use its index. You can still encounter errors if you have more than 8192 units on the map at a time, but if you do, then frankly you have other problems to worry about.
 
I wasnt thinking of official replacement. This was just an idea for personal use. And this solution seemed very simple. Use one row and then use it as index.

I guess the idea goes to the graveyard then :p

Yeah, if it works for your map then it is 100% fine. You just have to be careful about it, is all. :D
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
It's okay if you want to use it, just test if it exceeds the threshold and keep leaks cleaned. IIRC TimerUtils still use that kind of trick.
 
Level 14
Joined
Jun 27, 2008
Messages
1,325
Just use a unit Indexer or normal Hashtables.

Anyway if ur really interested in writing ur own hashing function you should think about how to resolve hash collisions. I dont think double hashing is a good idea, but you could use a linear search fallback.
Just if you want to play around with that stuff... for realworld triggers its not worth the effort. -> Use hashtables / Unit indexing.
 
Status
Not open for further replies.
Top